@atlassian/forge-conditions 0.3.3-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,120 @@
1
+ # @atlassian/forge-conditions
2
+
3
+ ## 0.3.3-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 9da1330: Add publishConfig
8
+
9
+ ## 0.3.2
10
+
11
+ ### Patch Changes
12
+
13
+ - a5e7647: Update license for Forge public packages
14
+
15
+ ## 0.3.2-next.0
16
+
17
+ ### Patch Changes
18
+
19
+ - a5e7647: Update license for Forge public packages
20
+
21
+ ## 0.3.1
22
+
23
+ ### Patch Changes
24
+
25
+ - 652e9f2: Bump Typescript and ESlint to latest
26
+
27
+ ## 0.3.1-next.0
28
+
29
+ ### Patch Changes
30
+
31
+ - 652e9f23: Bump Typescript and ESlint to latest
32
+
33
+ ## 0.3.0
34
+
35
+ ### Minor Changes
36
+
37
+ - 3367e8d: Update display conditions processing logic to support Confluence entity property conditions
38
+
39
+ ### Patch Changes
40
+
41
+ - 3f30fe8: Export types.ts as part of the library
42
+
43
+ ## 0.3.0-next.1
44
+
45
+ ### Patch Changes
46
+
47
+ - 3f30fe8: Export types.ts as part of the library
48
+
49
+ ## 0.3.0-next.0
50
+
51
+ ### Minor Changes
52
+
53
+ - 3367e8d: Update display conditions processing logic to support Confluence entity property conditions
54
+
55
+ ## 0.2.0
56
+
57
+ ### Minor Changes
58
+
59
+ - a55d9c8: Changed validation and runtime error messages for display conditions
60
+
61
+ ## 0.2.0-next.0
62
+
63
+ ### Minor Changes
64
+
65
+ - a55d9c8: Changed validation and runtime error messages for display conditions
66
+
67
+ ## 0.1.0
68
+
69
+ ### Minor Changes
70
+
71
+ - dd27c38: Add display condition types and validation
72
+
73
+ ### Patch Changes
74
+
75
+ - b41cc4c: Fix exported content
76
+ - 41dcd69: Moved CSP logic to its own package and bridge script to cli-shared
77
+
78
+ ## 0.1.0-next.2
79
+
80
+ ### Patch Changes
81
+
82
+ - 41dcd69: Moved CSP logic to its own package and bridge script to cli-shared
83
+
84
+ ## 0.1.0-next.1
85
+
86
+ ### Minor Changes
87
+
88
+ - dd27c38: Add display condition types and validation
89
+
90
+ ## 0.0.5-next.0
91
+
92
+ ### Patch Changes
93
+
94
+ - b41cc4c: Fix exported content
95
+
96
+ ## 0.0.4
97
+
98
+ ### Patch Changes
99
+
100
+ - 059a822: Set build target to ES5
101
+
102
+ ## 0.0.4-next.0
103
+
104
+ ### Patch Changes
105
+
106
+ - 059a822: Set build target to ES5
107
+
108
+ ## 0.0.3
109
+
110
+ ## 0.0.2
111
+
112
+ ### Patch Changes
113
+
114
+ - 1546f65: Add an initial version of Forge conditions
115
+
116
+ ## 0.0.2-next.0
117
+
118
+ ### Patch Changes
119
+
120
+ - 1546f65: Add an initial version of Forge conditions
package/LICENSE.txt ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2025 Atlassian
2
+ Permission is hereby granted to use this software in accordance with the terms
3
+ and conditions outlined in the Atlassian Developer Terms, which can be found
4
+ at the following URL:
5
+ https://developer.atlassian.com/platform/marketplace/atlassian-developer-terms/
6
+ By using this software, you agree to comply with these terms and conditions.
7
+ If you do not agree with these terms, you are not permitted to use this software.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # Forge conditions
2
+
3
+ The package validates provided conditions against provided data.
4
+ It compares the static data and supports few basic logical operations such as:
5
+ * and
6
+ * or
7
+ * not
8
+
9
+ ## How to use
10
+
11
+ Import `doesMeetConditions` and invoke it with two arguments to get a `boolean` result:
12
+ ```javascript
13
+ doesMeetConditions({}, {}) // true
14
+ doesMeetConditions({}, { isAdmin: false }) // true, no conditions
15
+ doesMeetConditions({ isAdmin: true }, { isAdmin: false }) // false, condition requires an admin
16
+ ```
17
+
18
+ Where the first argument defines what conditions have to be met, and the second one is a static data.
19
+
20
+ In case a top-level operation isn't specified, the `and` operation is applied.
21
+ It may be changed by specifying another operation though.
22
+
23
+ ### A full example of usage
24
+
25
+ ```javascript
26
+ import { doesMeetConditions } from '@atlassian/forge-conditions';
27
+
28
+ const conditions = {
29
+ isLoggedIn: true,
30
+ or: {
31
+ isAdmin: true,
32
+ anotherProp: ['this', 'or', 'whatever'],
33
+ }
34
+ };
35
+
36
+ const staticContext = {
37
+ isLoggedIn: true,
38
+ isAdmin: false,
39
+ anotherProp: 'this',
40
+ };
41
+
42
+ // true, because isLoggedIn matches and one of the `or` conditions matched as well
43
+ doesMeetConditions(conditions, staticContext);
44
+ ```
45
+
46
+ All supported operations can be nested if needed:
47
+
48
+ ```javascript
49
+ const conditions = {
50
+ or: {
51
+ isLoggedIn: true,
52
+ not: {
53
+ anotherProp: ['O_GOD_NOT_THIS_OH_NO_HELP_NOOOOOO'],
54
+ and: {
55
+ isAdmin: true,
56
+ not: {
57
+ issueType: 'Bug',
58
+ }
59
+ }
60
+ }
61
+ }
62
+ };
63
+ ```
package/out/check.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Conditions, StaticContext, ClientDataProvider } from './types';
2
+ export declare const doesMeetConditions: (conditions: Conditions, staticContext: StaticContext, clientDataProvider?: ClientDataProvider) => Promise<boolean> | boolean;
3
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkD,UAAU,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAoNxH,eAAO,MAAM,kBAAkB,eACjB,UAAU,iBACP,aAAa,uBACP,kBAAkB,KACtC,QAAQ,OAAO,CAAC,GAAG,OAwBrB,CAAC"}
package/out/check.js ADDED
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.doesMeetConditions = void 0;
4
+ const common_1 = require("./common");
5
+ const text_1 = require("./text");
6
+ const entity_property_1 = require("./condition-types/entity-property");
7
+ const unhandledOperation = (operation) => {
8
+ throw new Error(text_1.errors.unhandledOperation(operation));
9
+ };
10
+ const checkOperation = (operation, conditionsInput, staticContextInput, clientData) => {
11
+ const conditions = (0, common_1.isObjectOrArray)(conditionsInput) ? conditionsInput : {};
12
+ const staticContext = (0, common_1.isObject)(staticContextInput) ? staticContextInput : {};
13
+ let staticKeys = [];
14
+ let operationEntries = [];
15
+ let propertyConditions;
16
+ if (Array.isArray(conditions)) {
17
+ propertyConditions = conditions;
18
+ }
19
+ else {
20
+ staticKeys = Object.keys(conditions).filter(common_1.isStaticKey);
21
+ propertyConditions = Object.entries(conditions)
22
+ .filter(([key]) => (0, common_1.isEntityPropertyCondition)(key))
23
+ .map(([key, condition]) => ({ [key]: condition }));
24
+ operationEntries = Object.entries(conditions).filter(([key, _]) => (0, common_1.isOperation)(key));
25
+ }
26
+ const staticKeysLength = staticKeys.length;
27
+ const operationsLength = operationEntries.length;
28
+ const propertyConditionsLength = propertyConditions.length;
29
+ const staticEqualityComparator = (key) => (Array.isArray(conditions[key]) ? conditions[key] : [conditions[key]]).includes(staticContext[key]);
30
+ if (staticKeysLength === 0 && operationsLength === 0 && propertyConditionsLength === 0) {
31
+ return common_1.Instruction.Skip;
32
+ }
33
+ if (staticKeysLength !== 0 || propertyConditionsLength !== 0) {
34
+ let clientDataConditionResult;
35
+ switch (operation) {
36
+ case common_1.AND_OPERATION:
37
+ if (staticKeysLength && !staticKeys.every(staticEqualityComparator)) {
38
+ return false;
39
+ }
40
+ clientDataConditionResult = entity_property_1.entityPropertyHandlers[common_1.AND_OPERATION](propertyConditions, clientData);
41
+ if (clientDataConditionResult !== common_1.Instruction.Continue) {
42
+ return clientDataConditionResult;
43
+ }
44
+ break;
45
+ case common_1.OR_OPERATION:
46
+ if (staticKeysLength && staticKeys.some(staticEqualityComparator)) {
47
+ return true;
48
+ }
49
+ clientDataConditionResult = entity_property_1.entityPropertyHandlers[common_1.OR_OPERATION](propertyConditions, clientData);
50
+ if (clientDataConditionResult !== common_1.Instruction.Continue) {
51
+ return clientDataConditionResult;
52
+ }
53
+ break;
54
+ case common_1.NOT_OPERATION:
55
+ if (staticKeysLength && staticKeys.some((key) => !staticEqualityComparator(key))) {
56
+ return true;
57
+ }
58
+ clientDataConditionResult = entity_property_1.entityPropertyHandlers[common_1.NOT_OPERATION](propertyConditions, clientData);
59
+ if (clientDataConditionResult !== common_1.Instruction.Continue) {
60
+ return clientDataConditionResult;
61
+ }
62
+ break;
63
+ default:
64
+ return unhandledOperation(operation);
65
+ }
66
+ }
67
+ for (let index = 0; index < operationEntries.length; index += 1) {
68
+ const [nextOperation, nextConditions] = operationEntries[index];
69
+ const nextOperationResult = checkOperation(nextOperation, nextConditions, staticContext, clientData);
70
+ if (nextOperationResult === common_1.Instruction.NeedData) {
71
+ return nextOperationResult;
72
+ }
73
+ switch (operation) {
74
+ case common_1.AND_OPERATION:
75
+ if (nextOperationResult === false) {
76
+ return false;
77
+ }
78
+ if (nextOperationResult === common_1.Instruction.Skip && operationsLength === 1) {
79
+ return staticKeysLength + propertyConditionsLength === 0 ? common_1.Instruction.Skip : true;
80
+ }
81
+ break;
82
+ case common_1.OR_OPERATION:
83
+ if (nextOperationResult === true) {
84
+ return true;
85
+ }
86
+ if (nextOperationResult === common_1.Instruction.Skip && operationsLength === 1) {
87
+ return staticKeysLength + propertyConditionsLength === 0 ? common_1.Instruction.Skip : false;
88
+ }
89
+ break;
90
+ case common_1.NOT_OPERATION:
91
+ if (nextOperationResult === false) {
92
+ return true;
93
+ }
94
+ if (nextOperationResult === common_1.Instruction.Skip && operationsLength === 1) {
95
+ return staticKeysLength + propertyConditionsLength === 0 ? common_1.Instruction.Skip : false;
96
+ }
97
+ break;
98
+ default:
99
+ return unhandledOperation(operation);
100
+ }
101
+ }
102
+ switch (operation) {
103
+ case common_1.AND_OPERATION:
104
+ return true;
105
+ case common_1.OR_OPERATION:
106
+ return false;
107
+ case common_1.NOT_OPERATION:
108
+ return false;
109
+ default:
110
+ return unhandledOperation(operation);
111
+ }
112
+ };
113
+ const validateNesting = (conditionsInput, nesting = 0) => {
114
+ if (nesting >= 10) {
115
+ throw new Error(text_1.errors.nestingOvercomplicated());
116
+ }
117
+ const conditions = (0, common_1.isObjectOrArray)(conditionsInput) ? conditionsInput : {};
118
+ if (Array.isArray(conditions)) {
119
+ return;
120
+ }
121
+ Object.entries(conditions)
122
+ .filter(([key, _]) => (0, common_1.isOperation)(key))
123
+ .forEach(([_, condition]) => validateNesting(condition, nesting + 1));
124
+ };
125
+ const doesMeetConditions = (conditions, staticContext, clientDataProvider) => {
126
+ try {
127
+ validateNesting(conditions);
128
+ let result = checkOperation(common_1.AND_OPERATION, conditions, staticContext);
129
+ if (result !== common_1.Instruction.NeedData) {
130
+ return result === common_1.Instruction.Skip ? true : result;
131
+ }
132
+ if (!clientDataProvider) {
133
+ return false;
134
+ }
135
+ return clientDataProvider
136
+ .fetchPropertyValues((0, entity_property_1.collectEntityPropertiesToFetch)(conditions))
137
+ .then((clientData) => {
138
+ result = checkOperation(common_1.AND_OPERATION, conditions, staticContext, clientData);
139
+ return result === common_1.Instruction.Skip ? true : result;
140
+ })
141
+ .catch(() => false);
142
+ }
143
+ catch (_a) {
144
+ return false;
145
+ }
146
+ };
147
+ exports.doesMeetConditions = doesMeetConditions;
@@ -0,0 +1,16 @@
1
+ import { AndOperation, NotOperation, OrOperation, PropertyConditionType, SupportedOperations } from './types';
2
+ export declare const AND_OPERATION: AndOperation;
3
+ export declare const OR_OPERATION: OrOperation;
4
+ export declare const NOT_OPERATION: NotOperation;
5
+ export declare const SUPPORTED_OPERATIONS: SupportedOperations;
6
+ export declare enum Instruction {
7
+ Skip = "skip",
8
+ NeedData = "need-data",
9
+ Continue = "continue"
10
+ }
11
+ export declare const isObject: (x: any) => boolean;
12
+ export declare const isObjectOrArray: (x: any) => boolean;
13
+ export declare const isOperation: (key: string) => boolean;
14
+ export declare const isEntityPropertyCondition: (key: string) => key is PropertyConditionType;
15
+ export declare const isStaticKey: (key: string) => boolean;
16
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,YAAY,EAEZ,WAAW,EACX,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,aAAa,EAAE,YAAoB,CAAC;AACjD,eAAO,MAAM,YAAY,EAAE,WAAkB,CAAC;AAC9C,eAAO,MAAM,aAAa,EAAE,YAAoB,CAAC;AACjD,eAAO,MAAM,oBAAoB,EAAE,mBAAkE,CAAC;AAEtG,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,QAAQ,cAAc;IACtB,QAAQ,aAAa;CACtB;AAED,eAAO,MAAM,QAAQ,MAAO,GAAG,KAAG,OAAkE,CAAC;AACrG,eAAO,MAAM,eAAe,MAAO,GAAG,KAAG,OAA0C,CAAC;AAEpF,eAAO,MAAM,WAAW,QAAS,MAAM,KAAG,OAA0D,CAAC;AACrG,eAAO,MAAM,yBAAyB,QAAS,MAAM,iCACwB,CAAC;AAC9E,eAAO,MAAM,WAAW,QAAS,MAAM,KAAG,OAA4E,CAAC"}
package/out/common.js ADDED
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isStaticKey = exports.isEntityPropertyCondition = exports.isOperation = exports.isObjectOrArray = exports.isObject = exports.Instruction = exports.SUPPORTED_OPERATIONS = exports.NOT_OPERATION = exports.OR_OPERATION = exports.AND_OPERATION = void 0;
4
+ const types_1 = require("./types");
5
+ exports.AND_OPERATION = 'and';
6
+ exports.OR_OPERATION = 'or';
7
+ exports.NOT_OPERATION = 'not';
8
+ exports.SUPPORTED_OPERATIONS = [exports.AND_OPERATION, exports.OR_OPERATION, exports.NOT_OPERATION];
9
+ var Instruction;
10
+ (function (Instruction) {
11
+ Instruction["Skip"] = "skip";
12
+ Instruction["NeedData"] = "need-data";
13
+ Instruction["Continue"] = "continue";
14
+ })(Instruction = exports.Instruction || (exports.Instruction = {}));
15
+ const isObject = (x) => Object.prototype.toString.call(x) === '[object Object]';
16
+ exports.isObject = isObject;
17
+ const isObjectOrArray = (x) => (0, exports.isObject)(x) || Array.isArray(x);
18
+ exports.isObjectOrArray = isObjectOrArray;
19
+ const isOperation = (key) => exports.SUPPORTED_OPERATIONS.includes(key);
20
+ exports.isOperation = isOperation;
21
+ const isEntityPropertyCondition = (key) => Object.values(types_1.PropertyConditionType).includes(key);
22
+ exports.isEntityPropertyCondition = isEntityPropertyCondition;
23
+ const isStaticKey = (key) => !(0, exports.isOperation)(key) && !(0, exports.isEntityPropertyCondition)(key);
24
+ exports.isStaticKey = isStaticKey;
@@ -0,0 +1,9 @@
1
+ import { ClientData, Conditions, EntityPropertyCondition, PropertyValueRequest } from '../types';
2
+ import { Instruction } from '../common';
3
+ export declare const entityPropertyHandlers: {
4
+ and: (propertyConditions: EntityPropertyCondition[], clientData?: ClientData) => boolean | Instruction;
5
+ or: (propertyConditions: EntityPropertyCondition[], clientData?: ClientData) => boolean | Instruction;
6
+ not: (propertyConditions: EntityPropertyCondition[], clientData?: ClientData) => boolean | Instruction;
7
+ };
8
+ export declare const collectEntityPropertiesToFetch: (conditionsInput: Conditions) => PropertyValueRequest[];
9
+ //# sourceMappingURL=entity-property.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-property.d.ts","sourceRoot":"","sources":["../../src/condition-types/entity-property.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,UAAU,EAEV,uBAAuB,EAEvB,oBAAoB,EAErB,MAAM,UAAU,CAAC;AAElB,OAAO,EAIL,WAAW,EAIZ,MAAM,WAAW,CAAC;AAiHnB,eAAO,MAAM,sBAAsB;8BAxDb,uBAAuB,EAAE,eAChC,UAAU,KACtB,OAAO,GAAG,WAAW;6BAgBF,uBAAuB,EAAE,eAChC,UAAU,KACtB,OAAO,GAAG,WAAW;8BAgBF,uBAAuB,EAAE,eAChC,UAAU,KACtB,OAAO,GAAG,WAAW;CAsBvB,CAAC;AAgBF,eAAO,MAAM,8BAA8B,oBAAqB,UAAU,KAAG,oBAAoB,EAiChG,CAAC"}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectEntityPropertiesToFetch = exports.entityPropertyHandlers = void 0;
4
+ const types_1 = require("../types");
5
+ const text_1 = require("../text");
6
+ const common_1 = require("../common");
7
+ const asArray = (value) => (Array.isArray(value) ? value : [value]);
8
+ const entityId = (entityProperty) => [entityProperty.entity, entityProperty.propertyKey, entityProperty.objectName].filter(Boolean).join('-');
9
+ const doesEntityPropertyMatch = (condition, propertyValuesResponse) => {
10
+ const conditionType = Object.keys(condition)[0];
11
+ const conditionFields = condition[conditionType];
12
+ const id = entityId(conditionFields);
13
+ const propertyValue = propertyValuesResponse[id];
14
+ const expectedValue = conditionFields.value;
15
+ let propValueArray;
16
+ switch (conditionType) {
17
+ case types_1.PropertyConditionType.EntityPropertyExists:
18
+ return propertyValue != null;
19
+ case types_1.PropertyConditionType.EntityPropertyEqualTo:
20
+ return propertyValue === expectedValue;
21
+ case types_1.PropertyConditionType.EntityPropertyContainsAny:
22
+ propValueArray = asArray(propertyValue);
23
+ return asArray(expectedValue).some((expected) => propValueArray.includes(expected));
24
+ case types_1.PropertyConditionType.EntityPropertyContainsAll:
25
+ propValueArray = asArray(propertyValue);
26
+ return asArray(expectedValue).every((expected) => propValueArray.includes(expected));
27
+ default:
28
+ throw new Error(text_1.errors.unsupportedConditionType(conditionType));
29
+ }
30
+ };
31
+ const clientConditionsPreCheck = (clientDataConditionsLength, clientData) => {
32
+ if (!clientDataConditionsLength) {
33
+ return common_1.Instruction.Continue;
34
+ }
35
+ if (!clientData) {
36
+ return common_1.Instruction.NeedData;
37
+ }
38
+ };
39
+ const entityPropertyAndHandler = (propertyConditions, clientData) => {
40
+ const preCheck = clientConditionsPreCheck(propertyConditions.length, clientData);
41
+ if (preCheck) {
42
+ return preCheck;
43
+ }
44
+ if (!propertyConditions.every((propCondition) => doesEntityPropertyMatch(propCondition, clientData.propertyValues))) {
45
+ return false;
46
+ }
47
+ return common_1.Instruction.Continue;
48
+ };
49
+ const entityPropertyOrHandler = (propertyConditions, clientData) => {
50
+ const preCheck = clientConditionsPreCheck(propertyConditions.length, clientData);
51
+ if (preCheck) {
52
+ return preCheck;
53
+ }
54
+ if (propertyConditions.some((propCondition) => doesEntityPropertyMatch(propCondition, clientData.propertyValues))) {
55
+ return true;
56
+ }
57
+ return common_1.Instruction.Continue;
58
+ };
59
+ const entityPropertyNotHandler = (propertyConditions, clientData) => {
60
+ const preCheck = clientConditionsPreCheck(propertyConditions.length, clientData);
61
+ if (preCheck) {
62
+ return preCheck;
63
+ }
64
+ if (propertyConditions.some((propCondition) => !doesEntityPropertyMatch(propCondition, clientData.propertyValues))) {
65
+ return true;
66
+ }
67
+ return common_1.Instruction.Continue;
68
+ };
69
+ exports.entityPropertyHandlers = {
70
+ [common_1.AND_OPERATION]: entityPropertyAndHandler,
71
+ [common_1.OR_OPERATION]: entityPropertyOrHandler,
72
+ [common_1.NOT_OPERATION]: entityPropertyNotHandler
73
+ };
74
+ const buildPropertyValueRequest = (entityProperty) => {
75
+ return Object.assign({ id: entityId(entityProperty), entity: entityProperty.entity, propertyKey: entityProperty.propertyKey }, (entityProperty.objectName && { objectName: entityProperty.objectName }));
76
+ };
77
+ const collectEntityPropertiesToFetch = (conditionsInput) => {
78
+ const conditions = (0, common_1.isObjectOrArray)(conditionsInput) ? conditionsInput : {};
79
+ const propertyRequests = [];
80
+ if (Array.isArray(conditions)) {
81
+ for (const propertyCondition of conditions) {
82
+ const key = Object.keys(propertyCondition).find(common_1.isEntityPropertyCondition);
83
+ if (key) {
84
+ const entityProperty = propertyCondition[key];
85
+ propertyRequests.push(buildPropertyValueRequest(entityProperty));
86
+ }
87
+ }
88
+ return propertyRequests;
89
+ }
90
+ Object.entries(conditions)
91
+ .filter(([key, _]) => (0, common_1.isEntityPropertyCondition)(key))
92
+ .forEach(([_, condition]) => propertyRequests.push(buildPropertyValueRequest(condition)));
93
+ Object.entries(conditions)
94
+ .filter(([key, _]) => (0, common_1.isOperation)(key))
95
+ .forEach(([_, condition]) => propertyRequests.push(...(0, exports.collectEntityPropertiesToFetch)(condition)));
96
+ return propertyRequests;
97
+ };
98
+ exports.collectEntityPropertiesToFetch = collectEntityPropertiesToFetch;
package/out/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './check';
2
+ export * from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
package/out/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./check"), exports);
5
+ tslib_1.__exportStar(require("./types"), exports);
package/out/text.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { PropertyConditionType } from './types';
2
+ export declare const errors: {
3
+ nestingOvercomplicated: () => string;
4
+ unhandledOperation: (operation: never) => string;
5
+ unsupportedConditionType: (conditionType: PropertyConditionType) => string;
6
+ };
7
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD,eAAO,MAAM,MAAM;kCACW,MAAM;oCACF,KAAK,KAAG,MAAM;8CACJ,qBAAqB,KAAG,MAAM;CAEzE,CAAC"}
package/out/text.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.errors = void 0;
4
+ exports.errors = {
5
+ nestingOvercomplicated: () => 'Nesting of display conditions exceeds 10 levels',
6
+ unhandledOperation: (operation) => `Unhandled operation: ${operation}`,
7
+ unsupportedConditionType: (conditionType) => `Unsupported condition type: ${conditionType}`
8
+ };
package/out/types.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ export declare type AndOperation = 'and';
2
+ export declare type OrOperation = 'or';
3
+ export declare type NotOperation = 'not';
4
+ export declare type Operation = AndOperation | OrOperation | NotOperation;
5
+ export declare type SupportedOperations = [AndOperation, OrOperation, NotOperation];
6
+ export declare type GenericCondition<T> = AndCondition<T> | OrCondition<T> | NotCondition<T> | T;
7
+ export declare type AndCondition<T> = T & {
8
+ [key in AndOperation]: GenericCondition<T>;
9
+ };
10
+ export declare type OrCondition<T> = T & {
11
+ [key in OrOperation]: GenericCondition<T>;
12
+ };
13
+ export declare type NotCondition<T> = T & {
14
+ [key in NotOperation]: GenericCondition<T>;
15
+ };
16
+ export declare enum PropertyConditionType {
17
+ EntityPropertyExists = "entityPropertyExists",
18
+ EntityPropertyEqualTo = "entityPropertyEqualTo",
19
+ EntityPropertyContainsAny = "entityPropertyContainsAny",
20
+ EntityPropertyContainsAll = "entityPropertyContainsAll"
21
+ }
22
+ export declare enum EntityType {
23
+ Space = "space",
24
+ Content = "content"
25
+ }
26
+ export interface EntityProperty {
27
+ entity: EntityType;
28
+ propertyKey: string;
29
+ objectName?: string;
30
+ value: string | string[];
31
+ }
32
+ export declare type EntityPropertyCondition = {
33
+ [key in PropertyConditionType]?: EntityProperty;
34
+ };
35
+ export interface PropertyValueRequest {
36
+ id: string;
37
+ entity: EntityType;
38
+ propertyKey: string;
39
+ objectName?: string;
40
+ }
41
+ export interface PropertyValuesResponse {
42
+ [id: string]: string | string[];
43
+ }
44
+ export interface ClientData {
45
+ propertyValues: PropertyValuesResponse;
46
+ }
47
+ export declare class ClientDataProvider {
48
+ private readonly globalFetchPromise;
49
+ private globalFetchResolve?;
50
+ private globalFetchReject?;
51
+ propertyValueRequests: PropertyValueRequest[];
52
+ constructor();
53
+ fetchPropertyValues(propValueRequests: PropertyValueRequest[]): Promise<ClientData>;
54
+ resolve(clientData: ClientData): void;
55
+ reject(reason: any): void;
56
+ }
57
+ export declare type Condition = StaticContext | (StaticContext & EntityPropertyCondition) | EntityPropertyCondition[];
58
+ export declare type Conditions = GenericCondition<Condition>;
59
+ export declare type StaticContext = {
60
+ [key in string]: any;
61
+ };
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,oBAAY,YAAY,GAAG,KAAK,CAAC;AACjC,oBAAY,WAAW,GAAG,IAAI,CAAC;AAC/B,oBAAY,YAAY,GAAG,KAAK,CAAC;AAEjC,oBAAY,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,YAAY,CAAC;AAClE,oBAAY,mBAAmB,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;AAE5E,oBAAY,gBAAgB,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AACzF,oBAAY,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG;KAC/B,GAAG,IAAI,YAAY,GAAG,gBAAgB,CAAC,CAAC,CAAC;CAC3C,CAAC;AAEF,oBAAY,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG;KAC9B,GAAG,IAAI,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC;CAC1C,CAAC;AAEF,oBAAY,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG;KAC/B,GAAG,IAAI,YAAY,GAAG,gBAAgB,CAAC,CAAC,CAAC;CAC3C,CAAC;AAEF,oBAAY,qBAAqB;IAC/B,oBAAoB,yBAAyB;IAC7C,qBAAqB,0BAA0B;IAC/C,yBAAyB,8BAA8B;IACvD,yBAAyB,8BAA8B;CACxD;AAED,oBAAY,UAAU;IACpB,KAAK,UAAU;IACf,OAAO,YAAY;CACpB;AAKD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC1B;AAKD,oBAAY,uBAAuB,GAAG;KACnC,GAAG,IAAI,qBAAqB,CAAC,CAAC,EAAE,cAAc;CAChD,CAAC;AAKF,MAAM,WAAW,oBAAoB;IAInC,EAAE,EAAE,MAAM,CAAC;IAIX,MAAM,EAAE,UAAU,CAAC;IAInB,WAAW,EAAE,MAAM,CAAC;IAKpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAWD,MAAM,WAAW,sBAAsB;IACrC,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;CACjC;AAKD,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,sBAAsB,CAAC;CACxC;AAaD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAsB;IACzD,OAAO,CAAC,kBAAkB,CAAC,CAA8B;IACzD,OAAO,CAAC,iBAAiB,CAAC,CAAwB;IAKlD,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;;IAe9C,mBAAmB,CAAC,iBAAiB,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAanF,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IAYrC,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;CAG1B;AAQD,oBAAY,SAAS,GAAG,aAAa,GAAG,CAAC,aAAa,GAAG,uBAAuB,CAAC,GAAG,uBAAuB,EAAE,CAAC;AAK9G,oBAAY,UAAU,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAQrD,oBAAY,aAAa,GAAG;KACzB,GAAG,IAAI,MAAM,GAAG,GAAG;CACrB,CAAC"}
package/out/types.js ADDED
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClientDataProvider = exports.EntityType = exports.PropertyConditionType = void 0;
4
+ var PropertyConditionType;
5
+ (function (PropertyConditionType) {
6
+ PropertyConditionType["EntityPropertyExists"] = "entityPropertyExists";
7
+ PropertyConditionType["EntityPropertyEqualTo"] = "entityPropertyEqualTo";
8
+ PropertyConditionType["EntityPropertyContainsAny"] = "entityPropertyContainsAny";
9
+ PropertyConditionType["EntityPropertyContainsAll"] = "entityPropertyContainsAll";
10
+ })(PropertyConditionType = exports.PropertyConditionType || (exports.PropertyConditionType = {}));
11
+ var EntityType;
12
+ (function (EntityType) {
13
+ EntityType["Space"] = "space";
14
+ EntityType["Content"] = "content";
15
+ })(EntityType = exports.EntityType || (exports.EntityType = {}));
16
+ class ClientDataProvider {
17
+ constructor() {
18
+ this.globalFetchPromise = new Promise((resolve, reject) => {
19
+ this.globalFetchResolve = resolve;
20
+ this.globalFetchReject = reject;
21
+ });
22
+ this.propertyValueRequests = [];
23
+ }
24
+ fetchPropertyValues(propValueRequests) {
25
+ this.propertyValueRequests.push(...propValueRequests);
26
+ return this.globalFetchPromise;
27
+ }
28
+ resolve(clientData) {
29
+ var _a;
30
+ (_a = this.globalFetchResolve) === null || _a === void 0 ? void 0 : _a.call(this, clientData);
31
+ }
32
+ reject(reason) {
33
+ var _a;
34
+ (_a = this.globalFetchReject) === null || _a === void 0 ? void 0 : _a.call(this, reason);
35
+ }
36
+ }
37
+ exports.ClientDataProvider = ClientDataProvider;
package/package.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "@atlassian/forge-conditions",
3
+ "version": "0.3.3-next.0",
4
+ "description": "Support conditions in the forge apps",
5
+ "main": "out/index.js",
6
+ "license": "SEE LICENSE IN LICENSE.txt",
7
+ "scripts": {
8
+ "build": "yarn run clean && yarn run compile",
9
+ "compile": "tsc -b -v",
10
+ "clean": "rm -rf ./out && rm -f tsconfig.tsbuildinfo"
11
+ },
12
+ "publishConfig": {
13
+ "registry": "https://packages.atlassian.com/api/npm/npm-public/"
14
+ }
15
+ }