@lightdash/common 0.2572.2 → 0.2573.1

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 (178) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/authorization/space/spaceAccessResolver.d.ts +2 -3
  3. package/dist/cjs/authorization/space/spaceAccessResolver.d.ts.map +1 -1
  4. package/dist/cjs/authorization/space/spaceAccessResolver.js +14 -78
  5. package/dist/cjs/authorization/space/spaceAccessResolver.js.map +1 -1
  6. package/dist/cjs/authorization/space/spaceAccessResolver.test.js +18 -529
  7. package/dist/cjs/authorization/space/spaceAccessResolver.test.js.map +1 -1
  8. package/dist/cjs/compiler/exploreCompiler.d.ts.map +1 -1
  9. package/dist/cjs/compiler/exploreCompiler.js +5 -3
  10. package/dist/cjs/compiler/exploreCompiler.js.map +1 -1
  11. package/dist/cjs/compiler/filtersCompiler.d.ts.map +1 -1
  12. package/dist/cjs/compiler/filtersCompiler.js +1 -0
  13. package/dist/cjs/compiler/filtersCompiler.js.map +1 -1
  14. package/dist/cjs/dbt/schemas/lightdashMetadata.json +1 -0
  15. package/dist/cjs/ee/AiAgent/schemas/customMetrics.d.ts +148 -148
  16. package/dist/cjs/ee/AiAgent/schemas/filters/index.d.ts +180 -180
  17. package/dist/cjs/ee/AiAgent/schemas/filters/numberFilters.d.ts +12 -12
  18. package/dist/cjs/ee/AiAgent/schemas/filters/numberFilters.d.ts.map +1 -1
  19. package/dist/cjs/ee/AiAgent/schemas/filters/numberFilters.js +1 -0
  20. package/dist/cjs/ee/AiAgent/schemas/filters/numberFilters.js.map +1 -1
  21. package/dist/cjs/ee/AiAgent/schemas/tools/toolDashboardArgs.d.ts +1608 -1608
  22. package/dist/cjs/ee/AiAgent/schemas/tools/toolDashboardV2Args.d.ts +440 -440
  23. package/dist/cjs/ee/AiAgent/schemas/tools/toolProposeChangeArgs.d.ts +60 -60
  24. package/dist/cjs/ee/AiAgent/schemas/tools/toolRunMetricQueryArgs.d.ts +256 -256
  25. package/dist/cjs/ee/AiAgent/schemas/tools/toolRunQueryArgs.d.ts +256 -256
  26. package/dist/cjs/ee/AiAgent/schemas/tools/toolSearchFieldValuesArgs.d.ts +180 -180
  27. package/dist/cjs/ee/AiAgent/schemas/tools/toolTableVizArgs.d.ts +320 -320
  28. package/dist/cjs/ee/AiAgent/schemas/tools/toolTimeSeriesArgs.d.ts +320 -320
  29. package/dist/cjs/ee/AiAgent/schemas/tools/toolVerticalBarArgs.d.ts +320 -320
  30. package/dist/cjs/preAggregates/additivity.d.ts.map +1 -1
  31. package/dist/cjs/preAggregates/additivity.js +1 -0
  32. package/dist/cjs/preAggregates/additivity.js.map +1 -1
  33. package/dist/cjs/preAggregates/metricRepresentation.d.ts.map +1 -1
  34. package/dist/cjs/preAggregates/metricRepresentation.js +1 -0
  35. package/dist/cjs/preAggregates/metricRepresentation.js.map +1 -1
  36. package/dist/cjs/schemas/json/chart-as-code-1.0.json +443 -114
  37. package/dist/cjs/types/catalog.d.ts.map +1 -1
  38. package/dist/cjs/types/catalog.js +1 -0
  39. package/dist/cjs/types/catalog.js.map +1 -1
  40. package/dist/cjs/types/featureFlags.d.ts +0 -6
  41. package/dist/cjs/types/featureFlags.d.ts.map +1 -1
  42. package/dist/cjs/types/featureFlags.js +0 -6
  43. package/dist/cjs/types/featureFlags.js.map +1 -1
  44. package/dist/cjs/types/field.d.ts +1 -0
  45. package/dist/cjs/types/field.d.ts.map +1 -1
  46. package/dist/cjs/types/field.js +3 -0
  47. package/dist/cjs/types/field.js.map +1 -1
  48. package/dist/cjs/types/results.d.ts.map +1 -1
  49. package/dist/cjs/types/results.js +1 -0
  50. package/dist/cjs/types/results.js.map +1 -1
  51. package/dist/cjs/types/space.d.ts +0 -7
  52. package/dist/cjs/types/space.d.ts.map +1 -1
  53. package/dist/cjs/types/space.js.map +1 -1
  54. package/dist/cjs/utils/filters.d.ts.map +1 -1
  55. package/dist/cjs/utils/filters.js +1 -0
  56. package/dist/cjs/utils/filters.js.map +1 -1
  57. package/dist/cjs/utils/item.d.ts.map +1 -1
  58. package/dist/cjs/utils/item.js +1 -0
  59. package/dist/cjs/utils/item.js.map +1 -1
  60. package/dist/esm/.tsbuildinfo +1 -1
  61. package/dist/esm/authorization/space/spaceAccessResolver.d.ts +2 -3
  62. package/dist/esm/authorization/space/spaceAccessResolver.d.ts.map +1 -1
  63. package/dist/esm/authorization/space/spaceAccessResolver.js +6 -69
  64. package/dist/esm/authorization/space/spaceAccessResolver.js.map +1 -1
  65. package/dist/esm/authorization/space/spaceAccessResolver.test.js +19 -530
  66. package/dist/esm/authorization/space/spaceAccessResolver.test.js.map +1 -1
  67. package/dist/esm/compiler/exploreCompiler.d.ts.map +1 -1
  68. package/dist/esm/compiler/exploreCompiler.js +5 -3
  69. package/dist/esm/compiler/exploreCompiler.js.map +1 -1
  70. package/dist/esm/compiler/filtersCompiler.d.ts.map +1 -1
  71. package/dist/esm/compiler/filtersCompiler.js +1 -0
  72. package/dist/esm/compiler/filtersCompiler.js.map +1 -1
  73. package/dist/esm/dbt/schemas/lightdashMetadata.json +1 -0
  74. package/dist/esm/ee/AiAgent/schemas/customMetrics.d.ts +148 -148
  75. package/dist/esm/ee/AiAgent/schemas/filters/index.d.ts +180 -180
  76. package/dist/esm/ee/AiAgent/schemas/filters/numberFilters.d.ts +12 -12
  77. package/dist/esm/ee/AiAgent/schemas/filters/numberFilters.d.ts.map +1 -1
  78. package/dist/esm/ee/AiAgent/schemas/filters/numberFilters.js +1 -0
  79. package/dist/esm/ee/AiAgent/schemas/filters/numberFilters.js.map +1 -1
  80. package/dist/esm/ee/AiAgent/schemas/tools/toolDashboardArgs.d.ts +1608 -1608
  81. package/dist/esm/ee/AiAgent/schemas/tools/toolDashboardV2Args.d.ts +440 -440
  82. package/dist/esm/ee/AiAgent/schemas/tools/toolProposeChangeArgs.d.ts +60 -60
  83. package/dist/esm/ee/AiAgent/schemas/tools/toolRunMetricQueryArgs.d.ts +256 -256
  84. package/dist/esm/ee/AiAgent/schemas/tools/toolRunQueryArgs.d.ts +256 -256
  85. package/dist/esm/ee/AiAgent/schemas/tools/toolSearchFieldValuesArgs.d.ts +180 -180
  86. package/dist/esm/ee/AiAgent/schemas/tools/toolTableVizArgs.d.ts +320 -320
  87. package/dist/esm/ee/AiAgent/schemas/tools/toolTimeSeriesArgs.d.ts +320 -320
  88. package/dist/esm/ee/AiAgent/schemas/tools/toolVerticalBarArgs.d.ts +320 -320
  89. package/dist/esm/preAggregates/additivity.d.ts.map +1 -1
  90. package/dist/esm/preAggregates/additivity.js +1 -0
  91. package/dist/esm/preAggregates/additivity.js.map +1 -1
  92. package/dist/esm/preAggregates/metricRepresentation.d.ts.map +1 -1
  93. package/dist/esm/preAggregates/metricRepresentation.js +1 -0
  94. package/dist/esm/preAggregates/metricRepresentation.js.map +1 -1
  95. package/dist/esm/schemas/json/chart-as-code-1.0.json +443 -114
  96. package/dist/esm/types/catalog.d.ts.map +1 -1
  97. package/dist/esm/types/catalog.js +1 -0
  98. package/dist/esm/types/catalog.js.map +1 -1
  99. package/dist/esm/types/featureFlags.d.ts +0 -6
  100. package/dist/esm/types/featureFlags.d.ts.map +1 -1
  101. package/dist/esm/types/featureFlags.js +0 -6
  102. package/dist/esm/types/featureFlags.js.map +1 -1
  103. package/dist/esm/types/field.d.ts +1 -0
  104. package/dist/esm/types/field.d.ts.map +1 -1
  105. package/dist/esm/types/field.js +3 -0
  106. package/dist/esm/types/field.js.map +1 -1
  107. package/dist/esm/types/results.d.ts.map +1 -1
  108. package/dist/esm/types/results.js +1 -0
  109. package/dist/esm/types/results.js.map +1 -1
  110. package/dist/esm/types/space.d.ts +0 -7
  111. package/dist/esm/types/space.d.ts.map +1 -1
  112. package/dist/esm/types/space.js.map +1 -1
  113. package/dist/esm/utils/filters.d.ts.map +1 -1
  114. package/dist/esm/utils/filters.js +1 -0
  115. package/dist/esm/utils/filters.js.map +1 -1
  116. package/dist/esm/utils/item.d.ts.map +1 -1
  117. package/dist/esm/utils/item.js +1 -0
  118. package/dist/esm/utils/item.js.map +1 -1
  119. package/dist/types/.tsbuildinfo +1 -1
  120. package/dist/types/authorization/space/spaceAccessResolver.d.ts +2 -3
  121. package/dist/types/authorization/space/spaceAccessResolver.d.ts.map +1 -1
  122. package/dist/types/authorization/space/spaceAccessResolver.js +6 -69
  123. package/dist/types/authorization/space/spaceAccessResolver.js.map +1 -1
  124. package/dist/types/authorization/space/spaceAccessResolver.test.js +19 -530
  125. package/dist/types/authorization/space/spaceAccessResolver.test.js.map +1 -1
  126. package/dist/types/compiler/exploreCompiler.d.ts.map +1 -1
  127. package/dist/types/compiler/exploreCompiler.js +5 -3
  128. package/dist/types/compiler/exploreCompiler.js.map +1 -1
  129. package/dist/types/compiler/filtersCompiler.d.ts.map +1 -1
  130. package/dist/types/compiler/filtersCompiler.js +1 -0
  131. package/dist/types/compiler/filtersCompiler.js.map +1 -1
  132. package/dist/types/dbt/schemas/lightdashMetadata.json +1 -0
  133. package/dist/types/ee/AiAgent/schemas/customMetrics.d.ts +148 -148
  134. package/dist/types/ee/AiAgent/schemas/filters/index.d.ts +180 -180
  135. package/dist/types/ee/AiAgent/schemas/filters/numberFilters.d.ts +12 -12
  136. package/dist/types/ee/AiAgent/schemas/filters/numberFilters.d.ts.map +1 -1
  137. package/dist/types/ee/AiAgent/schemas/filters/numberFilters.js +1 -0
  138. package/dist/types/ee/AiAgent/schemas/filters/numberFilters.js.map +1 -1
  139. package/dist/types/ee/AiAgent/schemas/tools/toolDashboardArgs.d.ts +1608 -1608
  140. package/dist/types/ee/AiAgent/schemas/tools/toolDashboardV2Args.d.ts +440 -440
  141. package/dist/types/ee/AiAgent/schemas/tools/toolProposeChangeArgs.d.ts +60 -60
  142. package/dist/types/ee/AiAgent/schemas/tools/toolRunMetricQueryArgs.d.ts +256 -256
  143. package/dist/types/ee/AiAgent/schemas/tools/toolRunQueryArgs.d.ts +256 -256
  144. package/dist/types/ee/AiAgent/schemas/tools/toolSearchFieldValuesArgs.d.ts +180 -180
  145. package/dist/types/ee/AiAgent/schemas/tools/toolTableVizArgs.d.ts +320 -320
  146. package/dist/types/ee/AiAgent/schemas/tools/toolTimeSeriesArgs.d.ts +320 -320
  147. package/dist/types/ee/AiAgent/schemas/tools/toolVerticalBarArgs.d.ts +320 -320
  148. package/dist/types/preAggregates/additivity.d.ts.map +1 -1
  149. package/dist/types/preAggregates/additivity.js +1 -0
  150. package/dist/types/preAggregates/additivity.js.map +1 -1
  151. package/dist/types/preAggregates/metricRepresentation.d.ts.map +1 -1
  152. package/dist/types/preAggregates/metricRepresentation.js +1 -0
  153. package/dist/types/preAggregates/metricRepresentation.js.map +1 -1
  154. package/dist/types/schemas/json/chart-as-code-1.0.json +443 -114
  155. package/dist/types/types/catalog.d.ts.map +1 -1
  156. package/dist/types/types/catalog.js +1 -0
  157. package/dist/types/types/catalog.js.map +1 -1
  158. package/dist/types/types/featureFlags.d.ts +0 -6
  159. package/dist/types/types/featureFlags.d.ts.map +1 -1
  160. package/dist/types/types/featureFlags.js +0 -6
  161. package/dist/types/types/featureFlags.js.map +1 -1
  162. package/dist/types/types/field.d.ts +1 -0
  163. package/dist/types/types/field.d.ts.map +1 -1
  164. package/dist/types/types/field.js +3 -0
  165. package/dist/types/types/field.js.map +1 -1
  166. package/dist/types/types/results.d.ts.map +1 -1
  167. package/dist/types/types/results.js +1 -0
  168. package/dist/types/types/results.js.map +1 -1
  169. package/dist/types/types/space.d.ts +0 -7
  170. package/dist/types/types/space.d.ts.map +1 -1
  171. package/dist/types/types/space.js.map +1 -1
  172. package/dist/types/utils/filters.d.ts.map +1 -1
  173. package/dist/types/utils/filters.js +1 -0
  174. package/dist/types/utils/filters.js.map +1 -1
  175. package/dist/types/utils/item.d.ts.map +1 -1
  176. package/dist/types/utils/item.js +1 -0
  177. package/dist/types/utils/item.js.map +1 -1
  178. package/package.json +1 -1
@@ -4,518 +4,7 @@ const organizationMemberProfile_1 = require("../../types/organizationMemberProfi
4
4
  const projectMemberRole_1 = require("../../types/projectMemberRole");
5
5
  const space_1 = require("../../types/space");
6
6
  const spaceAccessResolver_1 = require("./spaceAccessResolver");
7
- const makeInput = (overrides = {}) => ({
8
- spaceUuid: 'space-1',
9
- inheritsFromOrgOrProject: true,
10
- directAccess: [],
11
- projectAccess: [],
12
- organizationAccess: [],
13
- ...overrides,
14
- });
15
7
  describe('resolveSpaceAccess', () => {
16
- it('returns empty array for empty inputs', () => {
17
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput());
18
- expect(result).toEqual([]);
19
- });
20
- describe('admin override', () => {
21
- it('org admin gets space ADMIN', () => {
22
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
23
- organizationAccess: [
24
- {
25
- userUuid: 'user-1',
26
- spaceUuid: 'space-1',
27
- role: organizationMemberProfile_1.OrganizationMemberRole.ADMIN,
28
- },
29
- ],
30
- }));
31
- expect(result).toHaveLength(1);
32
- expect(result[0].role).toBe(space_1.SpaceMemberRole.ADMIN);
33
- expect(result[0].inheritedFrom).toBe('organization');
34
- });
35
- it('project admin gets space ADMIN', () => {
36
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
37
- organizationAccess: [
38
- {
39
- userUuid: 'user-1',
40
- spaceUuid: 'space-1',
41
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
42
- },
43
- ],
44
- projectAccess: [
45
- {
46
- userUuid: 'user-1',
47
- spaceUuid: 'space-1',
48
- role: projectMemberRole_1.ProjectMemberRole.ADMIN,
49
- from: space_1.ProjectSpaceAccessOrigin.PROJECT_MEMBERSHIP,
50
- },
51
- ],
52
- }));
53
- expect(result).toHaveLength(1);
54
- expect(result[0].role).toBe(space_1.SpaceMemberRole.ADMIN);
55
- });
56
- it('group admin (project group) gets space ADMIN', () => {
57
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
58
- organizationAccess: [
59
- {
60
- userUuid: 'user-1',
61
- spaceUuid: 'space-1',
62
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
63
- },
64
- ],
65
- projectAccess: [
66
- {
67
- userUuid: 'user-1',
68
- spaceUuid: 'space-1',
69
- role: projectMemberRole_1.ProjectMemberRole.ADMIN,
70
- from: space_1.ProjectSpaceAccessOrigin.GROUP_MEMBERSHIP,
71
- },
72
- ],
73
- }));
74
- expect(result).toHaveLength(1);
75
- expect(result[0].role).toBe(space_1.SpaceMemberRole.ADMIN);
76
- });
77
- it('admin can access private space even without direct access', () => {
78
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
79
- inheritsFromOrgOrProject: false,
80
- organizationAccess: [
81
- {
82
- userUuid: 'user-1',
83
- spaceUuid: 'space-1',
84
- role: organizationMemberProfile_1.OrganizationMemberRole.ADMIN,
85
- },
86
- ],
87
- }));
88
- expect(result).toHaveLength(1);
89
- expect(result[0].role).toBe(space_1.SpaceMemberRole.ADMIN);
90
- });
91
- });
92
- describe('direct access', () => {
93
- it('USER_ACCESS role used directly', () => {
94
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
95
- organizationAccess: [
96
- {
97
- userUuid: 'user-1',
98
- spaceUuid: 'space-1',
99
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
100
- },
101
- ],
102
- directAccess: [
103
- {
104
- userUuid: 'user-1',
105
- spaceUuid: 'space-1',
106
- role: space_1.SpaceMemberRole.EDITOR,
107
- groupUuid: null,
108
- from: space_1.DirectSpaceAccessOrigin.USER_ACCESS,
109
- },
110
- ],
111
- }));
112
- expect(result).toHaveLength(1);
113
- expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
114
- expect(result[0].hasDirectAccess).toBe(true);
115
- });
116
- it('GROUP_ACCESS role used when no user role', () => {
117
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
118
- organizationAccess: [
119
- {
120
- userUuid: 'user-1',
121
- spaceUuid: 'space-1',
122
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
123
- },
124
- ],
125
- directAccess: [
126
- {
127
- userUuid: 'user-1',
128
- spaceUuid: 'space-1',
129
- role: space_1.SpaceMemberRole.EDITOR,
130
- groupUuid: 'group-1',
131
- from: space_1.DirectSpaceAccessOrigin.GROUP_ACCESS,
132
- },
133
- ],
134
- }));
135
- expect(result).toHaveLength(1);
136
- expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
137
- expect(result[0].hasDirectAccess).toBe(true);
138
- });
139
- it('user + group direct access: user role wins when higher', () => {
140
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
141
- organizationAccess: [
142
- {
143
- userUuid: 'user-1',
144
- spaceUuid: 'space-1',
145
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
146
- },
147
- ],
148
- directAccess: [
149
- {
150
- userUuid: 'user-1',
151
- spaceUuid: 'space-1',
152
- role: space_1.SpaceMemberRole.EDITOR,
153
- groupUuid: null,
154
- from: space_1.DirectSpaceAccessOrigin.USER_ACCESS,
155
- },
156
- {
157
- userUuid: 'user-1',
158
- spaceUuid: 'space-1',
159
- role: space_1.SpaceMemberRole.VIEWER,
160
- groupUuid: 'group-1',
161
- from: space_1.DirectSpaceAccessOrigin.GROUP_ACCESS,
162
- },
163
- ],
164
- }));
165
- expect(result).toHaveLength(1);
166
- // User access takes precedence over group access
167
- expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
168
- });
169
- });
170
- describe('public space inheritance', () => {
171
- it('viewer gets viewer space role', () => {
172
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
173
- inheritsFromOrgOrProject: true,
174
- organizationAccess: [
175
- {
176
- userUuid: 'user-1',
177
- spaceUuid: 'space-1',
178
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
179
- },
180
- ],
181
- }));
182
- expect(result).toHaveLength(1);
183
- expect(result[0].role).toBe(space_1.SpaceMemberRole.VIEWER);
184
- expect(result[0].hasDirectAccess).toBe(false);
185
- expect(result[0].inheritedFrom).toBe('organization');
186
- });
187
- it('editor gets editor space role', () => {
188
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
189
- inheritsFromOrgOrProject: true,
190
- organizationAccess: [
191
- {
192
- userUuid: 'user-1',
193
- spaceUuid: 'space-1',
194
- role: organizationMemberProfile_1.OrganizationMemberRole.EDITOR,
195
- },
196
- ],
197
- }));
198
- expect(result).toHaveLength(1);
199
- expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
200
- });
201
- it('developer gets editor space role', () => {
202
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
203
- inheritsFromOrgOrProject: true,
204
- organizationAccess: [
205
- {
206
- userUuid: 'user-1',
207
- spaceUuid: 'space-1',
208
- role: organizationMemberProfile_1.OrganizationMemberRole.DEVELOPER,
209
- },
210
- ],
211
- }));
212
- expect(result).toHaveLength(1);
213
- expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
214
- });
215
- it('interactive_viewer gets viewer space role', () => {
216
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
217
- inheritsFromOrgOrProject: true,
218
- organizationAccess: [
219
- {
220
- userUuid: 'user-1',
221
- spaceUuid: 'space-1',
222
- role: organizationMemberProfile_1.OrganizationMemberRole.INTERACTIVE_VIEWER,
223
- },
224
- ],
225
- }));
226
- expect(result).toHaveLength(1);
227
- expect(result[0].role).toBe(space_1.SpaceMemberRole.VIEWER);
228
- });
229
- });
230
- describe('private space exclusion', () => {
231
- it('non-admin without direct access excluded from private space', () => {
232
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
233
- inheritsFromOrgOrProject: false,
234
- organizationAccess: [
235
- {
236
- userUuid: 'user-1',
237
- spaceUuid: 'space-1',
238
- role: organizationMemberProfile_1.OrganizationMemberRole.EDITOR,
239
- },
240
- ],
241
- }));
242
- expect(result).toHaveLength(0);
243
- });
244
- it('private space with direct access works', () => {
245
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
246
- inheritsFromOrgOrProject: false,
247
- organizationAccess: [
248
- {
249
- userUuid: 'user-1',
250
- spaceUuid: 'space-1',
251
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
252
- },
253
- ],
254
- directAccess: [
255
- {
256
- userUuid: 'user-1',
257
- spaceUuid: 'space-1',
258
- role: space_1.SpaceMemberRole.EDITOR,
259
- groupUuid: null,
260
- from: space_1.DirectSpaceAccessOrigin.USER_ACCESS,
261
- },
262
- ],
263
- }));
264
- expect(result).toHaveLength(1);
265
- expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
266
- });
267
- });
268
- describe('org MEMBER role', () => {
269
- it('org MEMBER with no other access is excluded', () => {
270
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
271
- inheritsFromOrgOrProject: true,
272
- organizationAccess: [
273
- {
274
- userUuid: 'user-1',
275
- spaceUuid: 'space-1',
276
- role: organizationMemberProfile_1.OrganizationMemberRole.MEMBER,
277
- },
278
- ],
279
- }));
280
- // MEMBER converts to undefined project role, so no highest role → excluded
281
- expect(result).toHaveLength(0);
282
- });
283
- it('org MEMBER with project access is included', () => {
284
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
285
- inheritsFromOrgOrProject: true,
286
- organizationAccess: [
287
- {
288
- userUuid: 'user-1',
289
- spaceUuid: 'space-1',
290
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
291
- },
292
- ],
293
- projectAccess: [
294
- {
295
- userUuid: 'user-1',
296
- spaceUuid: 'space-1',
297
- role: projectMemberRole_1.ProjectMemberRole.EDITOR,
298
- from: space_1.ProjectSpaceAccessOrigin.PROJECT_MEMBERSHIP,
299
- },
300
- ],
301
- }));
302
- expect(result).toHaveLength(1);
303
- expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
304
- });
305
- });
306
- describe('multiple group roles', () => {
307
- it('highest group role wins', () => {
308
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
309
- inheritsFromOrgOrProject: true,
310
- organizationAccess: [
311
- {
312
- userUuid: 'user-1',
313
- spaceUuid: 'space-1',
314
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
315
- },
316
- ],
317
- projectAccess: [
318
- {
319
- userUuid: 'user-1',
320
- spaceUuid: 'space-1',
321
- role: projectMemberRole_1.ProjectMemberRole.VIEWER,
322
- from: space_1.ProjectSpaceAccessOrigin.GROUP_MEMBERSHIP,
323
- },
324
- {
325
- userUuid: 'user-1',
326
- spaceUuid: 'space-1',
327
- role: projectMemberRole_1.ProjectMemberRole.EDITOR,
328
- from: space_1.ProjectSpaceAccessOrigin.GROUP_MEMBERSHIP,
329
- },
330
- ],
331
- }));
332
- expect(result).toHaveLength(1);
333
- expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
334
- });
335
- });
336
- describe('inheritedFrom metadata', () => {
337
- it('reports organization when org role is highest', () => {
338
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
339
- organizationAccess: [
340
- {
341
- userUuid: 'user-1',
342
- spaceUuid: 'space-1',
343
- role: organizationMemberProfile_1.OrganizationMemberRole.EDITOR,
344
- },
345
- ],
346
- }));
347
- expect(result[0].inheritedFrom).toBe('organization');
348
- });
349
- it('reports project when project role is highest', () => {
350
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
351
- organizationAccess: [
352
- {
353
- userUuid: 'user-1',
354
- spaceUuid: 'space-1',
355
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
356
- },
357
- ],
358
- projectAccess: [
359
- {
360
- userUuid: 'user-1',
361
- spaceUuid: 'space-1',
362
- role: projectMemberRole_1.ProjectMemberRole.EDITOR,
363
- from: space_1.ProjectSpaceAccessOrigin.PROJECT_MEMBERSHIP,
364
- },
365
- ],
366
- }));
367
- expect(result[0].inheritedFrom).toBe('project');
368
- });
369
- it('reports group when group project role is highest', () => {
370
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
371
- organizationAccess: [
372
- {
373
- userUuid: 'user-1',
374
- spaceUuid: 'space-1',
375
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
376
- },
377
- ],
378
- projectAccess: [
379
- {
380
- userUuid: 'user-1',
381
- spaceUuid: 'space-1',
382
- role: projectMemberRole_1.ProjectMemberRole.DEVELOPER,
383
- from: space_1.ProjectSpaceAccessOrigin.GROUP_MEMBERSHIP,
384
- },
385
- ],
386
- }));
387
- expect(result[0].inheritedFrom).toBe('group');
388
- });
389
- it('reports space_group when space group access role is highest', () => {
390
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
391
- organizationAccess: [
392
- {
393
- userUuid: 'user-1',
394
- spaceUuid: 'space-1',
395
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
396
- },
397
- ],
398
- directAccess: [
399
- {
400
- userUuid: 'user-1',
401
- spaceUuid: 'space-1',
402
- role: space_1.SpaceMemberRole.EDITOR,
403
- groupUuid: 'group-1',
404
- from: space_1.DirectSpaceAccessOrigin.GROUP_ACCESS,
405
- },
406
- ],
407
- }));
408
- expect(result[0].inheritedFrom).toBe('space_group');
409
- });
410
- it('reports org access when org access is highest', () => {
411
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
412
- organizationAccess: [
413
- {
414
- userUuid: 'user-1',
415
- spaceUuid: 'space-1',
416
- role: organizationMemberProfile_1.OrganizationMemberRole.DEVELOPER,
417
- },
418
- ],
419
- directAccess: [
420
- {
421
- userUuid: 'user-1',
422
- spaceUuid: 'space-1',
423
- role: space_1.SpaceMemberRole.VIEWER,
424
- groupUuid: null,
425
- from: space_1.DirectSpaceAccessOrigin.USER_ACCESS,
426
- },
427
- ],
428
- }));
429
- expect(result[0].inheritedFrom).toBe('organization');
430
- // Direct user access takes precedence over inherited org role
431
- // for the space role, even if the org role is higher.
432
- // The org source is reflected in inheritedFrom/inheritedRole.
433
- expect(result[0].role).toBe(space_1.SpaceMemberRole.VIEWER);
434
- });
435
- });
436
- describe('projectRole field', () => {
437
- it('only considers org + direct project membership (not groups)', () => {
438
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
439
- organizationAccess: [
440
- {
441
- userUuid: 'user-1',
442
- spaceUuid: 'space-1',
443
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
444
- },
445
- ],
446
- projectAccess: [
447
- {
448
- userUuid: 'user-1',
449
- spaceUuid: 'space-1',
450
- role: projectMemberRole_1.ProjectMemberRole.DEVELOPER,
451
- from: space_1.ProjectSpaceAccessOrigin.GROUP_MEMBERSHIP,
452
- },
453
- ],
454
- }));
455
- // projectRole should be VIEWER (from org), not DEVELOPER (from group)
456
- expect(result[0].projectRole).toBe(projectMemberRole_1.ProjectMemberRole.VIEWER);
457
- });
458
- it('includes direct project membership in projectRole', () => {
459
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
460
- organizationAccess: [
461
- {
462
- userUuid: 'user-1',
463
- spaceUuid: 'space-1',
464
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
465
- },
466
- ],
467
- projectAccess: [
468
- {
469
- userUuid: 'user-1',
470
- spaceUuid: 'space-1',
471
- role: projectMemberRole_1.ProjectMemberRole.EDITOR,
472
- from: space_1.ProjectSpaceAccessOrigin.PROJECT_MEMBERSHIP,
473
- },
474
- ],
475
- }));
476
- expect(result[0].projectRole).toBe(projectMemberRole_1.ProjectMemberRole.EDITOR);
477
- });
478
- });
479
- describe('multiple users', () => {
480
- it('resolves access for multiple users independently', () => {
481
- const orgAccess = [
482
- {
483
- userUuid: 'user-1',
484
- spaceUuid: 'space-1',
485
- role: organizationMemberProfile_1.OrganizationMemberRole.EDITOR,
486
- },
487
- {
488
- userUuid: 'user-2',
489
- spaceUuid: 'space-1',
490
- role: organizationMemberProfile_1.OrganizationMemberRole.VIEWER,
491
- },
492
- ];
493
- const directAccess = [
494
- {
495
- userUuid: 'user-2',
496
- spaceUuid: 'space-1',
497
- role: space_1.SpaceMemberRole.ADMIN,
498
- groupUuid: null,
499
- from: space_1.DirectSpaceAccessOrigin.USER_ACCESS,
500
- },
501
- ];
502
- const projectAccess = [];
503
- const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeInput({
504
- organizationAccess: orgAccess,
505
- directAccess,
506
- projectAccess,
507
- }));
508
- expect(result).toHaveLength(2);
509
- const user1 = result.find((r) => r.userUuid === 'user-1');
510
- const user2 = result.find((r) => r.userUuid === 'user-2');
511
- expect(user1?.role).toBe(space_1.SpaceMemberRole.EDITOR);
512
- expect(user1?.hasDirectAccess).toBe(false);
513
- expect(user2?.role).toBe(space_1.SpaceMemberRole.ADMIN);
514
- expect(user2?.hasDirectAccess).toBe(true);
515
- });
516
- });
517
- });
518
- describe('resolveSpaceAccessWithInheritance', () => {
519
8
  const makeChainInput = (overrides = {}) => ({
520
9
  spaceUuid: 'child-space',
521
10
  inheritsFromOrgOrProject: true,
@@ -525,12 +14,12 @@ describe('resolveSpaceAccessWithInheritance', () => {
525
14
  ...overrides,
526
15
  });
527
16
  it('returns empty array for empty inputs', () => {
528
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput());
17
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput());
529
18
  expect(result).toEqual([]);
530
19
  });
531
20
  describe('single-space chain (backward compat)', () => {
532
21
  it('org admin gets space ADMIN', () => {
533
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
22
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
534
23
  chainDirectAccess: [
535
24
  { spaceUuid: 'child-space', directAccess: [] },
536
25
  ],
@@ -546,7 +35,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
546
35
  expect(result[0].role).toBe(space_1.SpaceMemberRole.ADMIN);
547
36
  });
548
37
  it('direct user access on single space resolves correctly', () => {
549
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
38
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
550
39
  chainDirectAccess: [
551
40
  {
552
41
  spaceUuid: 'child-space',
@@ -576,7 +65,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
576
65
  });
577
66
  describe('most permissive wins across chain', () => {
578
67
  it('USER_ACCESS EDITOR on parent beats USER_ACCESS VIEWER on child', () => {
579
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
68
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
580
69
  chainDirectAccess: [
581
70
  {
582
71
  spaceUuid: 'child-space',
@@ -616,7 +105,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
616
105
  expect(result[0].hasDirectAccess).toBe(true);
617
106
  });
618
107
  it('GROUP_ACCESS EDITOR on parent beats USER_ACCESS VIEWER on child', () => {
619
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
108
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
620
109
  chainDirectAccess: [
621
110
  {
622
111
  spaceUuid: 'child-space',
@@ -655,7 +144,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
655
144
  expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
656
145
  });
657
146
  it('USER_ACCESS EDITOR on child already wins (child is higher)', () => {
658
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
147
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
659
148
  chainDirectAccess: [
660
149
  {
661
150
  spaceUuid: 'child-space',
@@ -694,7 +183,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
694
183
  expect(result[0].role).toBe(space_1.SpaceMemberRole.EDITOR);
695
184
  });
696
185
  it('three-level chain: grandparent ADMIN wins over child VIEWER', () => {
697
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
186
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
698
187
  chainDirectAccess: [
699
188
  {
700
189
  spaceUuid: 'child-space',
@@ -739,7 +228,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
739
228
  });
740
229
  describe('hasDirectAccess', () => {
741
230
  it('is false when user has direct access only on parent (inherited)', () => {
742
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
231
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
743
232
  chainDirectAccess: [
744
233
  { spaceUuid: 'child-space', directAccess: [] },
745
234
  {
@@ -767,7 +256,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
767
256
  expect(result[0].hasDirectAccess).toBe(false);
768
257
  });
769
258
  it('is true when user has direct access on the leaf space', () => {
770
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
259
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
771
260
  chainDirectAccess: [
772
261
  {
773
262
  spaceUuid: 'child-space',
@@ -794,7 +283,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
794
283
  expect(result[0].hasDirectAccess).toBe(true);
795
284
  });
796
285
  it('is false when user has group access only on parent', () => {
797
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
286
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
798
287
  chainDirectAccess: [
799
288
  { spaceUuid: 'child-space', directAccess: [] },
800
289
  {
@@ -823,7 +312,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
823
312
  expect(result[0].inheritedFrom).toBe('parent_space');
824
313
  });
825
314
  it('is false when user has only project/org access', () => {
826
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
315
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
827
316
  chainDirectAccess: [
828
317
  { spaceUuid: 'child-space', directAccess: [] },
829
318
  ],
@@ -841,7 +330,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
841
330
  });
842
331
  describe('inheritedFrom metadata', () => {
843
332
  it('reports parent_space when winning role is from ancestor', () => {
844
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
333
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
845
334
  chainDirectAccess: [
846
335
  { spaceUuid: 'child-space', directAccess: [] },
847
336
  {
@@ -869,7 +358,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
869
358
  expect(result[0].inheritedFrom).toBe('parent_space');
870
359
  });
871
360
  it('reports parent_space when group access is from ancestor', () => {
872
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
361
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
873
362
  chainDirectAccess: [
874
363
  { spaceUuid: 'child-space', directAccess: [] },
875
364
  {
@@ -898,7 +387,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
898
387
  expect(result[0].hasDirectAccess).toBe(false);
899
388
  });
900
389
  it('does not report parent_space when winning role is from leaf', () => {
901
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
390
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
902
391
  chainDirectAccess: [
903
392
  {
904
393
  spaceUuid: 'child-space',
@@ -927,7 +416,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
927
416
  });
928
417
  describe('private chain', () => {
929
418
  it('no access without direct access on private chain', () => {
930
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
419
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
931
420
  inheritsFromOrgOrProject: false,
932
421
  chainDirectAccess: [
933
422
  { spaceUuid: 'child-space', directAccess: [] },
@@ -951,7 +440,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
951
440
  expect(result).toHaveLength(0);
952
441
  });
953
442
  it('admin without direct access is excluded (CASL handles admin access)', () => {
954
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
443
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
955
444
  inheritsFromOrgOrProject: false,
956
445
  chainDirectAccess: [
957
446
  { spaceUuid: 'child-space', directAccess: [] },
@@ -967,7 +456,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
967
456
  expect(result).toHaveLength(0);
968
457
  });
969
458
  it('direct access on parent grants access on private child', () => {
970
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
459
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
971
460
  inheritsFromOrgOrProject: false,
972
461
  chainDirectAccess: [
973
462
  { spaceUuid: 'child-space', directAccess: [] },
@@ -998,7 +487,7 @@ describe('resolveSpaceAccessWithInheritance', () => {
998
487
  });
999
488
  describe('multiple users', () => {
1000
489
  it('resolves each user independently', () => {
1001
- const result = (0, spaceAccessResolver_1.resolveSpaceAccessWithInheritance)(makeChainInput({
490
+ const result = (0, spaceAccessResolver_1.resolveSpaceAccess)(makeChainInput({
1002
491
  chainDirectAccess: [
1003
492
  {
1004
493
  spaceUuid: 'child-space',