@azure/app-configuration-importer 1.0.1-preview → 1.1.0-preview

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.
@@ -0,0 +1,122 @@
1
+ import { RequirementType, StatusOverride } from "./featureFlag";
2
+ export const MsFeatureFlagValueSchema = {
3
+ type: "object",
4
+ properties: {
5
+ id: { type: "string" },
6
+ description: { type: "string", nullable: true },
7
+ enabled: { type: "boolean", nullable: true },
8
+ conditions: {
9
+ type: "object",
10
+ nullable: true,
11
+ properties: {
12
+ client_filters: {
13
+ type: "array",
14
+ minItems: 0,
15
+ nullable: true,
16
+ items: {
17
+ type: "object",
18
+ properties: {
19
+ name: { type: "string" },
20
+ parameters: { type: "object", nullable: true }
21
+ },
22
+ required: ["name"]
23
+ }
24
+ },
25
+ requirement_type: {
26
+ type: "string",
27
+ nullable: true,
28
+ enum: [RequirementType.All, RequirementType.Any]
29
+ }
30
+ }
31
+ },
32
+ display_name: { type: "string", nullable: true },
33
+ allocation: {
34
+ type: "object",
35
+ nullable: true,
36
+ properties: {
37
+ user: {
38
+ type: "array",
39
+ nullable: true,
40
+ items: {
41
+ type: "object",
42
+ properties: {
43
+ variant: { type: "string" },
44
+ users: {
45
+ type: "array",
46
+ items: { type: "string" }
47
+ }
48
+ },
49
+ required: ["variant", "users"]
50
+ }
51
+ },
52
+ group: {
53
+ type: "array",
54
+ nullable: true,
55
+ items: {
56
+ type: "object",
57
+ properties: {
58
+ variant: { type: "string" },
59
+ groups: {
60
+ type: "array",
61
+ items: { type: "string" }
62
+ }
63
+ },
64
+ required: ["variant", "groups"]
65
+ }
66
+ },
67
+ default_when_enabled: { type: "string", nullable: true },
68
+ default_when_disabled: { type: "string", nullable: true },
69
+ percentile: {
70
+ type: "array",
71
+ nullable: true,
72
+ items: {
73
+ type: "object",
74
+ properties: {
75
+ variant: { type: "string" },
76
+ from: { type: "number", minimum: 0, maximum: 100 },
77
+ to: { type: "number", minimum: 0, maximum: 100 }
78
+ },
79
+ required: ["variant", "from", "to"]
80
+ }
81
+ },
82
+ seed: { type: "string", nullable: true }
83
+ }
84
+ },
85
+ variants: {
86
+ type: "array",
87
+ nullable: true,
88
+ items: {
89
+ type: "object",
90
+ properties: {
91
+ name: { type: "string" },
92
+ configuration_value: {
93
+ oneOf: [
94
+ { type: "string" },
95
+ { type: "number" },
96
+ { type: "object", additionalProperties: true },
97
+ { type: "boolean" },
98
+ { type: "array" },
99
+ { type: "null" }
100
+ ]
101
+ },
102
+ status_override: {
103
+ type: "string",
104
+ nullable: true,
105
+ enum: [StatusOverride.None, StatusOverride.Enabled, StatusOverride.Disabled]
106
+ }
107
+ },
108
+ required: ["name"]
109
+ }
110
+ },
111
+ telemetry: {
112
+ type: "object",
113
+ nullable: true,
114
+ properties: {
115
+ enabled: { type: "boolean", nullable: true },
116
+ metadata: { type: "object", nullable: true }
117
+ }
118
+ }
119
+ },
120
+ required: ["id"]
121
+ };
122
+ //# sourceMappingURL=MsFeatureFlagSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MsFeatureFlagSchema.js","sourceRoot":"","sources":["../../src/MsFeatureFlagSchema.ts"],"names":[],"mappings":"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","sourcesContent":["import { RequirementType, StatusOverride } from \"./featureFlag\";\n\nexport const MsFeatureFlagValueSchema = {\n type: \"object\",\n properties: {\n id: { type: \"string\" },\n description: { type: \"string\", nullable: true },\n enabled: { type: \"boolean\", nullable: true },\n conditions: {\n type: \"object\",\n nullable: true,\n properties: {\n client_filters: {\n type: \"array\",\n minItems: 0,\n nullable: true,\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\"},\n parameters: { type: \"object\", nullable: true }\n },\n required: [\"name\"]\n }\n },\n requirement_type: {\n type: \"string\",\n nullable: true,\n enum: [RequirementType.All, RequirementType.Any] }\n }\n },\n display_name: { type: \"string\", nullable: true },\n allocation: {\n type: \"object\",\n nullable: true,\n properties: {\n user: {\n type: \"array\",\n nullable: true,\n items: {\n type: \"object\",\n properties: {\n variant: { type: \"string\" },\n users: {\n type: \"array\",\n items: { type: \"string\" }\n }\n },\n required: [\"variant\", \"users\"]\n }\n },\n group: {\n type: \"array\",\n nullable: true,\n items: {\n type: \"object\",\n properties: {\n variant: { type: \"string\" },\n groups: {\n type: \"array\",\n items: { type: \"string\" }\n }\n },\n required: [\"variant\", \"groups\"]\n }\n },\n default_when_enabled: { type: \"string\", nullable: true },\n default_when_disabled: { type: \"string\", nullable: true },\n percentile: {\n type: \"array\",\n nullable: true,\n items: {\n type: \"object\",\n properties: {\n variant: { type: \"string\" },\n from: { type: \"number\", minimum: 0, maximum: 100 },\n to: { type: \"number\", minimum: 0, maximum: 100 }\n },\n required: [\"variant\", \"from\", \"to\"]\n }\n },\n seed: { type: \"string\", nullable: true }\n }\n },\n variants: {\n type: \"array\",\n nullable: true,\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n configuration_value: { \n oneOf: [\n { type: \"string\" },\n { type: \"number\" },\n { type: \"object\", additionalProperties: true },\n { type: \"boolean\"},\n { type: \"array\"},\n { type: \"null\"}\n ]} as any,\n status_override: {\n type: \"string\",\n nullable: true,\n enum: [StatusOverride.None, StatusOverride.Enabled, StatusOverride.Disabled]\n }\n },\n required: [\"name\"]\n }\n },\n telemetry: {\n type: \"object\",\n nullable: true,\n properties: {\n enabled: { type: \"boolean\", nullable: true },\n metadata: { type: \"object\", nullable: true }\n }\n }\n },\n required: [\"id\"]\n};"]}
@@ -32,4 +32,22 @@ export class OperationTimeoutError extends Error {
32
32
  */
33
33
  export class ArgumentNullError extends Error {
34
34
  }
35
+ export class AjvValidationError extends Error {
36
+ constructor(validationErrors) {
37
+ super();
38
+ this.errors = this.parseAjvErrors(validationErrors);
39
+ }
40
+ parseAjvErrors(validationErrors) {
41
+ return validationErrors.map(error => ({
42
+ schemaPath: error.schemaPath,
43
+ message: error.message || ""
44
+ }));
45
+ }
46
+ getFriendlyMessage() {
47
+ return this.errors.map(error => {
48
+ const property = error.schemaPath ? `Property '${error.schemaPath}'` : "A property";
49
+ return `${property} ${error.message}`;
50
+ }).join(", ");
51
+ }
52
+ }
35
53
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAGnC,YAAY,OAAe;QACzB,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,mEAAmE,CAAC;IACrF,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;CAAG","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Custom error type used during input validation\n */\nexport class ArgumentError extends Error {\n constructor(message: string) {\n super();\n\n this.message = message;\n }\n}\n\n/**\n * Custom error type used during configuration file parsing\n */\nexport class ParseError extends Error {\n public message: string;\n\n constructor(message: string) {\n super();\n\n this.message = message;\n }\n}\n\n/**\n * Custom error type used for set configuration timeout error\n */\nexport class OperationTimeoutError extends Error {\n constructor() {\n super();\n this.message = \"The operation failed to complete within the specified time limit.\";\n }\n}\n\n/**\n * Custom error type used when null arguments are passed\n */\nexport class ArgumentNullError extends Error {}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC;;GAEG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAGnC,YAAY,OAAe;QACzB,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,OAAO,GAAG,mEAAmE,CAAC;IACrF,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;CAAG;AAO/C,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAG3C,YAAY,gBAA+B;QACzC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;IACtD,CAAC;IAEO,cAAc,CAAC,gBAA+B;QACpD,OAAO,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACpC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;SAC7B,CAAC,CAAC,CAAC;IACN,CAAC;IAEM,kBAAkB;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;YAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC;YACpF,OAAO,GAAG,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACxC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { ErrorObject } from \"ajv\";\n\n/**\n * Custom error type used during input validation\n */\nexport class ArgumentError extends Error {\n constructor(message: string) {\n super();\n\n this.message = message;\n }\n}\n\n/**\n * Custom error type used during configuration file parsing\n */\nexport class ParseError extends Error {\n public message: string;\n\n constructor(message: string) {\n super();\n\n this.message = message;\n }\n}\n\n/**\n * Custom error type used for set configuration timeout error\n */\nexport class OperationTimeoutError extends Error {\n constructor() {\n super();\n this.message = \"The operation failed to complete within the specified time limit.\";\n }\n}\n\n/**\n * Custom error type used when null arguments are passed\n */\nexport class ArgumentNullError extends Error {}\n\nexport interface AjvErrorInfo {\n schemaPath: string;\n message: string;\n}\n\nexport class AjvValidationError extends Error {\n public errors: AjvErrorInfo[];\n\n constructor(validationErrors: ErrorObject[]) {\n super();\n this.errors = this.parseAjvErrors(validationErrors);\n }\n\n private parseAjvErrors(validationErrors: ErrorObject[]): AjvErrorInfo[] {\n return validationErrors.map(error => ({\n schemaPath: error.schemaPath,\n message: error.message || \"\"\n }));\n }\n\n public getFriendlyMessage(): string {\n return this.errors.map(error => {\n const property = error.schemaPath ? `Property '${error.schemaPath}'` : \"A property\";\n return `${property} ${error.message}`;\n }).join(\", \");\n }\n}"]}
@@ -0,0 +1,12 @@
1
+ export var RequirementType;
2
+ (function (RequirementType) {
3
+ RequirementType["Any"] = "Any";
4
+ RequirementType["All"] = "All";
5
+ })(RequirementType || (RequirementType = {}));
6
+ export var StatusOverride;
7
+ (function (StatusOverride) {
8
+ StatusOverride["None"] = "None";
9
+ StatusOverride["Enabled"] = "Enabled";
10
+ StatusOverride["Disabled"] = "Disabled";
11
+ })(StatusOverride || (StatusOverride = {}));
12
+ //# sourceMappingURL=featureFlag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureFlag.js","sourceRoot":"","sources":["../../src/featureFlag.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAN,IAAY,eAGX;AAHD,WAAY,eAAe;IACvB,8BAAW,CAAA;IACX,8BAAW,CAAA;AACf,CAAC,EAHW,eAAe,KAAf,eAAe,QAG1B;AAED,MAAM,CAAN,IAAY,cAIX;AAJD,WAAY,cAAc;IACtB,+BAAa,CAAA;IACb,qCAAoB,CAAA;IACpB,uCAAqB,CAAA;AACzB,CAAC,EAJW,cAAc,KAAd,cAAc,QAIzB","sourcesContent":["import { ClientFilter } from \"./models\";\nimport { FeatureFlagValue } from \"@azure/app-configuration\";\n\nexport interface MsFeatureFlagValue extends FeatureFlagValue {\n conditions: {\n clientFilters: ClientFilter[];\n requirementType?: RequirementType\n };\n allocation?: Allocation;\n variants?: Variant[];\n telemetry?: {\n enabled?: boolean;\n metadata?: object;\n };\n}\n\nexport enum RequirementType {\n Any = \"Any\",\n All = \"All\"\n}\n\nexport enum StatusOverride {\n None = \"None\",\n Enabled = \"Enabled\",\n Disabled = \"Disabled\"\n}\n\nexport interface Allocation {\n user?: User [];\n group?: Group[];\n default_when_enabled?: string;\n default_when_disabled?: string;\n percentile?: Percentile[];\n seed?: string;\n}\n\nexport interface User {\n variant: string;\n users: string[]\n}\n\nexport interface Group {\n variant: string;\n groups: string[]\n}\n\nexport interface Percentile {\n variant: string;\n from: number;\n to: number;\n}\n\nexport interface Variant {\n name: string;\n configuration_value?: string | number | object | boolean;\n status_override?: StatusOverride;\n}"]}
@@ -5,14 +5,20 @@ export const Constants = {
5
5
  FeatureManagementKeyWords: [
6
6
  "FeatureManagement",
7
7
  "featureManagement",
8
- "feature_management",
9
- "feature-management"
8
+ "feature-management",
9
+ "feature_management"
10
10
  ],
11
11
  EnabledForKeyWords: [
12
12
  "EnabledFor",
13
13
  "enabledFor",
14
- "enabled_for",
15
- "enabled-for"
14
+ "enabled-for",
15
+ "enabled_for"
16
+ ],
17
+ RequirementTypeKeyWords: [
18
+ "RequirementType",
19
+ "requirementType",
20
+ "requirement-type",
21
+ "requirement_type"
16
22
  ],
17
23
  Separators: [
18
24
  ".",
@@ -24,6 +30,7 @@ export const Constants = {
24
30
  "/",
25
31
  ":"
26
32
  ],
27
- CorrelationRequestIdHeader: "x-ms-correlation-request-id"
33
+ CorrelationRequestIdHeader: "x-ms-correlation-request-id",
34
+ FeatureFlagsKeyWord: "feature_flags"
28
35
  };
29
36
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/internal/constants.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,eAAe;AACf,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,yBAAyB,EAAE;QACzB,mBAAmB;QACnB,mBAAmB;QACnB,oBAAoB;QACpB,oBAAoB;KACrB;IACD,kBAAkB,EAAE;QAClB,YAAY;QACZ,YAAY;QACZ,aAAa;QACb,aAAa;KACd;IACD,UAAU,EAAE;QACV,GAAG;QACH,GAAG;QACH,GAAG;QACH,GAAG;QACH,GAAG;QACH,IAAI;QACJ,GAAG;QACH,GAAG;KACJ;IACD,0BAA0B,EAAE,6BAA6B;CAC1D,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/** @internal*/\nexport const Constants = {\n FeatureManagementKeyWords: [\n \"FeatureManagement\",\n \"featureManagement\",\n \"feature_management\",\n \"feature-management\"\n ],\n EnabledForKeyWords: [\n \"EnabledFor\",\n \"enabledFor\",\n \"enabled_for\",\n \"enabled-for\"\n ],\n Separators: [\n \".\",\n \",\",\n \";\",\n \"-\",\n \"_\",\n \"__\",\n \"/\",\n \":\"\n ],\n CorrelationRequestIdHeader: \"x-ms-correlation-request-id\"\n};\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/internal/constants.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,eAAe;AACf,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,yBAAyB,EAAE;QACzB,mBAAmB;QACnB,mBAAmB;QACnB,oBAAoB;QACpB,oBAAoB;KACrB;IACD,kBAAkB,EAAE;QAClB,YAAY;QACZ,YAAY;QACZ,aAAa;QACb,aAAa;KACd;IACD,uBAAuB,EAAE;QACvB,iBAAiB;QACjB,iBAAiB;QACjB,kBAAkB;QAClB,kBAAkB;KACnB;IACD,UAAU,EAAE;QACV,GAAG;QACH,GAAG;QACH,GAAG;QACH,GAAG;QACH,GAAG;QACH,IAAI;QACJ,GAAG;QACH,GAAG;KACJ;IACD,0BAA0B,EAAE,6BAA6B;IACzD,mBAAmB,EAAE,eAAe;CACrC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/** @internal*/\nexport const Constants = {\n FeatureManagementKeyWords: [\n \"FeatureManagement\",\n \"featureManagement\",\n \"feature-management\",\n \"feature_management\"\n ],\n EnabledForKeyWords: [\n \"EnabledFor\",\n \"enabledFor\",\n \"enabled-for\",\n \"enabled_for\"\n ],\n RequirementTypeKeyWords: [\n \"RequirementType\",\n \"requirementType\",\n \"requirement-type\",\n \"requirement_type\"\n ],\n Separators: [\n \".\",\n \",\",\n \";\",\n \"-\",\n \"_\",\n \"__\",\n \"/\",\n \":\"\n ],\n CorrelationRequestIdHeader: \"x-ms-correlation-request-id\",\n FeatureFlagsKeyWord: \"feature_flags\"\n};\n"]}
@@ -1,11 +1,25 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
+ var __rest = (this && this.__rest) || function (s, e) {
4
+ var t = {};
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
6
+ t[p] = s[p];
7
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
8
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
9
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
10
+ t[p[i]] = s[p[i]];
11
+ }
12
+ return t;
13
+ };
3
14
  import { featureFlagPrefix, featureFlagContentType } from "@azure/app-configuration";
4
- import { Constants } from "../constants";
5
- import { ArgumentError } from "../../errors";
15
+ import { AjvValidationError, ArgumentError } from "../../errors";
6
16
  import * as flat from "flat";
7
17
  import { ConfigurationFormat } from "../../enums";
8
18
  import { isJsonContentType } from "../utils";
19
+ import { RequirementType } from "../../featureFlag";
20
+ import { Constants } from "../constants";
21
+ import { MsFeatureFlagValueSchema } from "../../MsFeatureFlagSchema";
22
+ import Ajv from "ajv";
9
23
  /**
10
24
  * Format Parser for common key-value configuration.
11
25
  *
@@ -21,29 +35,45 @@ export class DefaultConfigurationSettingsConverter {
21
35
  Convert(config, options) {
22
36
  let configurationSettings = new Array();
23
37
  let featureFlagsConfigSettings = new Array();
24
- let foundFeatureManagement = false;
25
- let featureFlags = {};
26
- let featureManagementKeyWord = "";
27
- let enabledForKeyWord = "";
38
+ let foundMsFmSchema = false;
39
+ let foundDotnetFmSchema = false;
40
+ let dotnetFmSchemaKeyWord = "";
41
+ const featureFlagsDict = {};
28
42
  if (options.format == ConfigurationFormat.Properties && !options.skipFeatureFlags) {
29
43
  this.checkFeatureManagementExist(config);
30
44
  }
31
- for (let i = 0; i < Constants.FeatureManagementKeyWords.length; i++) {
45
+ for (let i = 0; i < Constants.FeatureManagementKeyWords.length - 1; i++) {
32
46
  if (Constants.FeatureManagementKeyWords[i] in config) {
33
- if (foundFeatureManagement) {
34
- throw new ArgumentError("Unable to proceed because data contains multiple sections corresponding to Feature Management.");
47
+ if (foundDotnetFmSchema) {
48
+ throw new ArgumentError(`Unable to proceed because data contains multiple sections corresponding to Feature Management. with the key, ${Constants.FeatureManagementKeyWords[i]}`);
35
49
  }
36
- featureManagementKeyWord = Constants.FeatureManagementKeyWords[i];
37
- enabledForKeyWord = Constants.EnabledForKeyWords[i];
38
- const featureManagementKey = featureManagementKeyWord;
39
- featureFlags = config[featureManagementKey];
40
- delete config[featureManagementKey];
41
- foundFeatureManagement = true;
50
+ foundDotnetFmSchema = true;
51
+ dotnetFmSchemaKeyWord = Constants.FeatureManagementKeyWords[i];
52
+ const dotnetFmSchemaKey = dotnetFmSchemaKeyWord;
53
+ featureFlagsDict[dotnetFmSchemaKey] = config[dotnetFmSchemaKey];
54
+ delete config[dotnetFmSchemaKey];
42
55
  }
43
56
  }
44
- if (foundFeatureManagement && !options.skipFeatureFlags) {
45
- const featureFlagConverter = new FeatureFlagConfigurationSettingsConverter(featureManagementKeyWord, enabledForKeyWord);
46
- featureFlagsConfigSettings = featureFlagConverter.Convert(featureFlags, options);
57
+ const msFeatureManagementKeyWord = Constants.FeatureManagementKeyWords[3];
58
+ if (msFeatureManagementKeyWord in config) {
59
+ if (foundDotnetFmSchema &&
60
+ Object.keys(config[msFeatureManagementKeyWord]).some(key => key !== Constants.FeatureFlagsKeyWord)) {
61
+ throw new ArgumentError(`Unable to proceed because data contains an already defined dotnet schema section with the key, ${dotnetFmSchemaKeyWord}.`);
62
+ }
63
+ if (Object.keys(config[msFeatureManagementKeyWord]).includes(Constants.FeatureFlagsKeyWord)) {
64
+ foundMsFmSchema = true;
65
+ }
66
+ if (Object.keys(config[msFeatureManagementKeyWord]).some(key => key !== Constants.FeatureFlagsKeyWord)) {
67
+ foundDotnetFmSchema = true;
68
+ dotnetFmSchemaKeyWord = msFeatureManagementKeyWord;
69
+ }
70
+ const featureManagementKey = msFeatureManagementKeyWord;
71
+ featureFlagsDict[featureManagementKey] = config[featureManagementKey];
72
+ delete config[featureManagementKey];
73
+ }
74
+ if ((foundDotnetFmSchema || foundMsFmSchema) && !options.skipFeatureFlags) {
75
+ const featureFlagConverter = new FeatureFlagConfigurationSettingsConverter(dotnetFmSchemaKeyWord, foundMsFmSchema);
76
+ featureFlagsConfigSettings = featureFlagConverter.Convert(featureFlagsDict, options);
47
77
  }
48
78
  const flattenedConfigurationSettings = flat.flatten(config, {
49
79
  delimiter: options.separator,
@@ -101,10 +131,11 @@ export class DefaultConfigurationSettingsConverter {
101
131
  * @internal
102
132
  * */
103
133
  class FeatureFlagConfigurationSettingsConverter {
104
- constructor(featureManagementKeyWord, enabledForKeyWord) {
105
- this.featureManagementKeyWord = featureManagementKeyWord;
106
- this.enabledForKeyWord = enabledForKeyWord;
107
- if (!this.featureManagementKeyWord || !this.enabledForKeyWord) {
134
+ constructor(dotnetFmSchemaKeyWord, foundMsFeatureManagement) {
135
+ this.dotnetFmSchemaKeyWord = dotnetFmSchemaKeyWord;
136
+ this.foundMsFeatureManagement = foundMsFeatureManagement;
137
+ this.ajv = new Ajv();
138
+ if (!this.dotnetFmSchemaKeyWord && !this.foundMsFeatureManagement) {
108
139
  throw new ArgumentError("No feature management was found");
109
140
  }
110
141
  }
@@ -114,18 +145,49 @@ class FeatureFlagConfigurationSettingsConverter {
114
145
  Convert(config, options) {
115
146
  var _a;
116
147
  const settings = new Array();
117
- for (const featureFlag in config) {
118
- if (!this.validateFeatureName(featureFlag)) {
119
- throw new ArgumentError(`Feature flag ${featureFlag} contains invalid character,'%' and ':' are not allowed in feature name. Please provide valid feature name.`);
148
+ const featureFlags = new Array();
149
+ if (this.dotnetFmSchemaKeyWord) {
150
+ const dotnetSchemaFeatureFlags = this.getDotnetFmSchemaFeatureFlags(config);
151
+ const featureManagementIndex = Constants.FeatureManagementKeyWords.indexOf(this.dotnetFmSchemaKeyWord);
152
+ for (const featureFlag in dotnetSchemaFeatureFlags) {
153
+ if (!this.validateFeatureName(featureFlag)) {
154
+ throw new ArgumentError(`Feature flag ${featureFlag} contains invalid character,'%' and ':' are not allowed in feature name. Please provide valid feature name.`);
155
+ }
156
+ const featureFlagValue = this.getFeatureFlagValueFromDotnetSchema(featureFlag, dotnetSchemaFeatureFlags[featureFlag], Constants.EnabledForKeyWords[featureManagementIndex], Constants.RequirementTypeKeyWords[featureManagementIndex]);
157
+ featureFlags.push(featureFlagValue);
158
+ }
159
+ }
160
+ if (this.foundMsFeatureManagement) {
161
+ const msFmSectionFeatureFlags = this.getMsFmSchemaFeatureFlags(config);
162
+ for (const featureFlag of msFmSectionFeatureFlags) {
163
+ if (!featureFlag.id) {
164
+ throw new ArgumentError("Feature flag without id is found, id is a required property.");
165
+ }
166
+ if (!this.validateFeatureName(featureFlag.id)) {
167
+ throw new ArgumentError(`Feature flag id ${featureFlag.id} contains invalid character,'%' and ':' are not allowed.`);
168
+ }
169
+ const featureFlagValue = this.getFeatureFlagValueFromMsFmSchema(featureFlag);
170
+ // Check if the featureFlag with the same id already exists
171
+ // Replace the existing flag with the later one, the later one always wins
172
+ const indexOfExistingFlag = featureFlags.findIndex(existingFeatureFlag => existingFeatureFlag.id === featureFlag.id);
173
+ if (indexOfExistingFlag !== -1) {
174
+ featureFlags[indexOfExistingFlag] = featureFlagValue;
175
+ }
176
+ else {
177
+ featureFlags.push(featureFlagValue);
178
+ }
120
179
  }
121
- const prefix = (_a = options.prefix) !== null && _a !== void 0 ? _a : "";
122
- settings.push({
123
- key: featureFlagPrefix + prefix + featureFlag,
180
+ }
181
+ const prefix = (_a = options.prefix) !== null && _a !== void 0 ? _a : "";
182
+ for (const featureFlag of featureFlags) {
183
+ const setting = {
184
+ key: featureFlagPrefix + prefix + featureFlag.id,
124
185
  label: options.label,
125
- value: this.getFeatureFlagValue(featureFlag, config, this.enabledForKeyWord),
186
+ value: featureFlag,
126
187
  contentType: featureFlagContentType,
127
188
  tags: options.tags
128
- });
189
+ };
190
+ settings.push(setting);
129
191
  }
130
192
  return settings;
131
193
  }
@@ -138,7 +200,7 @@ class FeatureFlagConfigurationSettingsConverter {
138
200
  return false;
139
201
  }
140
202
  }
141
- getFeatureFlagValue(featureFlagName, featureData, enabledForKeyWord) {
203
+ getFeatureFlagValueFromDotnetSchema(featureFlagName, featureData, enabledForKeyWord, requirementTypeKeyWord) {
142
204
  const defaultFeatureConditions = { clientFilters: [] };
143
205
  const featureFlagValue = {
144
206
  id: featureFlagName,
@@ -148,46 +210,80 @@ class FeatureFlagConfigurationSettingsConverter {
148
210
  clientFilters: []
149
211
  }
150
212
  };
151
- if (typeof featureData[featureFlagName] == "object") {
152
- const filters = featureData[featureFlagName][enabledForKeyWord];
213
+ if (typeof featureData == "object") {
214
+ const filters = featureData[enabledForKeyWord];
153
215
  if (!filters) {
154
216
  throw new ArgumentError(`Data contains feature flags in invalid format. Feature flag '${featureFlagName}' must contain '${enabledForKeyWord}' definition or have a true/false value.`);
155
217
  }
156
218
  if (filters.length != 0) {
157
219
  featureFlagValue.enabled = true;
158
220
  featureFlagValue.conditions.clientFilters = filters;
159
- for (let i = 0; i < featureFlagValue.conditions.clientFilters.length; i++) {
160
- const parameters = {};
161
- //
162
- // Converting client_filter keys to lower case
163
- const lowerCaseFilters = this.getLowerCaseFilters(featureFlagValue.conditions.clientFilters[i]);
164
- const filtersName = lowerCaseFilters["name"];
165
- const filtersParameters = lowerCaseFilters["parameters"];
166
- if (filtersName) {
167
- if (filtersName.toLowerCase() == "alwayson") {
168
- featureFlagValue.conditions = defaultFeatureConditions;
169
- break;
221
+ if (featureFlagValue.conditions && featureFlagValue.conditions.clientFilters) {
222
+ for (let i = 0; i < featureFlagValue.conditions.clientFilters.length; i++) {
223
+ const parameters = {};
224
+ //
225
+ // Converting client_filter keys to lower case
226
+ const lowerCaseFilters = this.getLowerCaseFilters(featureFlagValue.conditions.clientFilters[i]);
227
+ const filtersName = lowerCaseFilters["name"];
228
+ const filtersParameters = lowerCaseFilters["parameters"];
229
+ if (filtersName) {
230
+ if (filtersName.toLowerCase() == "alwayson") {
231
+ featureFlagValue.conditions = defaultFeatureConditions;
232
+ break;
233
+ }
234
+ parameters.name = filtersName;
235
+ if (filtersParameters) {
236
+ parameters.parameters = filtersParameters;
237
+ }
238
+ featureFlagValue.conditions.clientFilters[i] = parameters;
170
239
  }
171
- parameters.name = filtersName;
172
- if (filtersParameters) {
173
- parameters.parameters = filtersParameters;
240
+ else {
241
+ throw new ArgumentError(`This feature flag '${featureFlagName}' has a filter without the required 'name' property.`);
174
242
  }
175
- featureFlagValue.conditions.clientFilters[i] = parameters;
176
- }
177
- else {
178
- throw new ArgumentError(`This feature flag '${featureFlagName}' has a filter without the required 'name' property.`);
179
243
  }
180
244
  }
181
245
  }
246
+ const requirementType = featureData[requirementTypeKeyWord];
247
+ if (requirementType) {
248
+ if (this.validateRequirementType(featureFlagName, requirementType)) {
249
+ featureFlagValue.conditions.requirementType = requirementType;
250
+ }
251
+ }
182
252
  }
183
- else if (typeof featureData[featureFlagName] == "boolean") {
184
- featureFlagValue.enabled = featureData[featureFlagName];
253
+ else if (typeof featureData == "boolean") {
254
+ featureFlagValue.enabled = featureData;
185
255
  }
186
256
  else {
187
257
  throw new ArgumentError(`Data contains feature flags in invalid format. The type of ${featureFlagName} should be either boolean or dictionary.`);
188
258
  }
189
259
  return featureFlagValue;
190
260
  }
261
+ getFeatureFlagValueFromMsFmSchema(featureFlag) {
262
+ var _a, _b, _c;
263
+ const validate = this.ajv.compile(MsFeatureFlagValueSchema);
264
+ const featureFlagCopy = JSON.parse(JSON.stringify(featureFlag)); //deep copy
265
+ // normalize client filters
266
+ if (featureFlagCopy.conditions && featureFlagCopy.conditions.client_filters) {
267
+ for (let i = 0; i < featureFlagCopy.conditions.client_filters.length; i++) {
268
+ featureFlagCopy.conditions.client_filters[i] = this.getLowerCaseFilters(featureFlagCopy.conditions.client_filters[i]);
269
+ }
270
+ }
271
+ const valid = validate(featureFlagCopy);
272
+ if (!valid) {
273
+ const validationError = new AjvValidationError(validate.errors);
274
+ throw new ArgumentError(`Feature flag '${featureFlag.id}' is not in the correct format. ${validationError.getFriendlyMessage()}`);
275
+ }
276
+ const parsedFeatureFlag = Object.assign(Object.assign({}, featureFlag), { conditions: {
277
+ clientFilters: (_b = (_a = featureFlag.conditions) === null || _a === void 0 ? void 0 : _a.client_filters) !== null && _b !== void 0 ? _b : []
278
+ } });
279
+ if (featureFlag.display_name) {
280
+ parsedFeatureFlag.displayName = featureFlag.display_name;
281
+ }
282
+ if ((_c = featureFlag.conditions) === null || _c === void 0 ? void 0 : _c.requirement_type) {
283
+ parsedFeatureFlag.conditions.requirementType = featureFlag.conditions.requirement_type;
284
+ }
285
+ return parsedFeatureFlag;
286
+ }
191
287
  getLowerCaseFilters(clientFilter) {
192
288
  const keys = Object.keys(clientFilter);
193
289
  const lowerCaseFilters = {};
@@ -196,5 +292,37 @@ class FeatureFlagConfigurationSettingsConverter {
196
292
  }
197
293
  return lowerCaseFilters;
198
294
  }
295
+ validateRequirementType(requirement_type, featureFlagName) {
296
+ if (!Object.values(RequirementType).includes(requirement_type)) {
297
+ throw new ArgumentError(`This feature flag '${featureFlagName}' must have any/all requirement type.`);
298
+ }
299
+ return true;
300
+ }
301
+ getMsFmSchemaFeatureFlags(config) {
302
+ const msFeatureManagementKeyWord = Constants.FeatureManagementKeyWords[3];
303
+ const featureManagementKey = msFeatureManagementKeyWord;
304
+ const featureManagementSection = config[featureManagementKey];
305
+ if (typeof featureManagementSection !== "object") {
306
+ throw new ArgumentError(`The ${msFeatureManagementKeyWord} section must be an object.`);
307
+ }
308
+ if (!Array.isArray(featureManagementSection[Constants.FeatureFlagsKeyWord])) {
309
+ throw new ArgumentError(`The ${Constants.FeatureFlagsKeyWord} key within ${msFeatureManagementKeyWord} must be an array.`);
310
+ }
311
+ return featureManagementSection[Constants.FeatureFlagsKeyWord];
312
+ }
313
+ getDotnetFmSchemaFeatureFlags(config) {
314
+ const msFeatureManagementKeyWord = Constants.FeatureManagementKeyWords[3];
315
+ const featureManagementSection = config[this.dotnetFmSchemaKeyWord];
316
+ if (typeof featureManagementSection !== "object") {
317
+ throw new ArgumentError(`The ${this.dotnetFmSchemaKeyWord} section must be an object.`);
318
+ }
319
+ if (this.dotnetFmSchemaKeyWord === msFeatureManagementKeyWord) { //dotnet schema might be nested within msFmSchema
320
+ const _a = featureManagementSection, { feature_flags } = _a, dotnetSchemaFeatureFlags = __rest(_a, ["feature_flags"]);
321
+ return dotnetSchemaFeatureFlags;
322
+ }
323
+ else {
324
+ return featureManagementSection;
325
+ }
326
+ }
199
327
  }
200
328
  //# sourceMappingURL=defaultConfigurationSettingsConverter.js.map