@messagevisor/core 0.0.1 → 0.1.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.
Files changed (211) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/LICENSE +21 -0
  3. package/README.md +7 -0
  4. package/jest.config.js +8 -0
  5. package/lib/benchmark/index.d.ts +2 -0
  6. package/lib/benchmark/index.js +417 -0
  7. package/lib/benchmark/index.js.map +1 -0
  8. package/lib/builder/index.d.ts +70 -0
  9. package/lib/builder/index.js +831 -0
  10. package/lib/builder/index.js.map +1 -0
  11. package/lib/cli/index.d.ts +28 -0
  12. package/lib/cli/index.js +182 -0
  13. package/lib/cli/index.js.map +1 -0
  14. package/lib/config/index.d.ts +61 -0
  15. package/lib/config/index.js +255 -0
  16. package/lib/config/index.js.map +1 -0
  17. package/lib/create/index.d.ts +2 -0
  18. package/lib/create/index.js +405 -0
  19. package/lib/create/index.js.map +1 -0
  20. package/lib/datasource/filesystemAdapter.d.ts +44 -0
  21. package/lib/datasource/filesystemAdapter.js +424 -0
  22. package/lib/datasource/filesystemAdapter.js.map +1 -0
  23. package/lib/datasource/index.d.ts +39 -0
  24. package/lib/datasource/index.js +96 -0
  25. package/lib/datasource/index.js.map +1 -0
  26. package/lib/error.d.ts +6 -0
  27. package/lib/error.js +49 -0
  28. package/lib/error.js.map +1 -0
  29. package/lib/evaluate/cli.d.ts +8 -0
  30. package/lib/evaluate/cli.js +179 -0
  31. package/lib/evaluate/cli.js.map +1 -0
  32. package/lib/evaluate/index.d.ts +10 -0
  33. package/lib/evaluate/index.js +131 -0
  34. package/lib/evaluate/index.js.map +1 -0
  35. package/lib/examples/coerceExampleIsoDates.d.ts +12 -0
  36. package/lib/examples/coerceExampleIsoDates.js +81 -0
  37. package/lib/examples/coerceExampleIsoDates.js.map +1 -0
  38. package/lib/examples/index.d.ts +63 -0
  39. package/lib/examples/index.js +713 -0
  40. package/lib/examples/index.js.map +1 -0
  41. package/lib/exporter/index.d.ts +60 -0
  42. package/lib/exporter/index.js +610 -0
  43. package/lib/exporter/index.js.map +1 -0
  44. package/lib/find-duplicates/index.d.ts +41 -0
  45. package/lib/find-duplicates/index.js +297 -0
  46. package/lib/find-duplicates/index.js.map +1 -0
  47. package/lib/generate-code/index.d.ts +11 -0
  48. package/lib/generate-code/index.js +157 -0
  49. package/lib/generate-code/index.js.map +1 -0
  50. package/lib/generate-code/typescript.d.ts +14 -0
  51. package/lib/generate-code/typescript.js +307 -0
  52. package/lib/generate-code/typescript.js.map +1 -0
  53. package/lib/importer/index.d.ts +64 -0
  54. package/lib/importer/index.js +1092 -0
  55. package/lib/importer/index.js.map +1 -0
  56. package/lib/index.d.ts +18 -0
  57. package/lib/index.js +35 -0
  58. package/lib/index.js.map +1 -0
  59. package/lib/info/index.d.ts +17 -0
  60. package/lib/info/index.js +132 -0
  61. package/lib/info/index.js.map +1 -0
  62. package/lib/init/index.d.ts +30 -0
  63. package/lib/init/index.js +348 -0
  64. package/lib/init/index.js.map +1 -0
  65. package/lib/lint/index.d.ts +1 -0
  66. package/lib/lint/index.js +6 -0
  67. package/lib/lint/index.js.map +1 -0
  68. package/lib/linter/attributeSchema.d.ts +7 -0
  69. package/lib/linter/attributeSchema.js +36 -0
  70. package/lib/linter/attributeSchema.js.map +1 -0
  71. package/lib/linter/checkLocaleCircularDependency.d.ts +7 -0
  72. package/lib/linter/checkLocaleCircularDependency.js +42 -0
  73. package/lib/linter/checkLocaleCircularDependency.js.map +1 -0
  74. package/lib/linter/conditionSchema.d.ts +3 -0
  75. package/lib/linter/conditionSchema.js +283 -0
  76. package/lib/linter/conditionSchema.js.map +1 -0
  77. package/lib/linter/formatSchema.d.ts +325 -0
  78. package/lib/linter/formatSchema.js +165 -0
  79. package/lib/linter/formatSchema.js.map +1 -0
  80. package/lib/linter/icuStyleLint.d.ts +6 -0
  81. package/lib/linter/icuStyleLint.js +226 -0
  82. package/lib/linter/icuStyleLint.js.map +1 -0
  83. package/lib/linter/index.d.ts +34 -0
  84. package/lib/linter/index.js +557 -0
  85. package/lib/linter/index.js.map +1 -0
  86. package/lib/linter/localeSchema.d.ts +672 -0
  87. package/lib/linter/localeSchema.js +50 -0
  88. package/lib/linter/localeSchema.js.map +1 -0
  89. package/lib/linter/messageSchema.d.ts +35 -0
  90. package/lib/linter/messageSchema.js +115 -0
  91. package/lib/linter/messageSchema.js.map +1 -0
  92. package/lib/linter/printError.d.ts +8 -0
  93. package/lib/linter/printError.js +41 -0
  94. package/lib/linter/printError.js.map +1 -0
  95. package/lib/linter/schema.d.ts +33 -0
  96. package/lib/linter/schema.js +192 -0
  97. package/lib/linter/schema.js.map +1 -0
  98. package/lib/linter/segmentSchema.d.ts +8 -0
  99. package/lib/linter/segmentSchema.js +18 -0
  100. package/lib/linter/segmentSchema.js.map +1 -0
  101. package/lib/linter/targetSchema.d.ts +337 -0
  102. package/lib/linter/targetSchema.js +39 -0
  103. package/lib/linter/targetSchema.js.map +1 -0
  104. package/lib/linter/testSchema.d.ts +71 -0
  105. package/lib/linter/testSchema.js +165 -0
  106. package/lib/linter/testSchema.js.map +1 -0
  107. package/lib/linter/zodHelpers.d.ts +2 -0
  108. package/lib/linter/zodHelpers.js +15 -0
  109. package/lib/linter/zodHelpers.js.map +1 -0
  110. package/lib/list/index.d.ts +8 -0
  111. package/lib/list/index.js +524 -0
  112. package/lib/list/index.js.map +1 -0
  113. package/lib/matrix.d.ts +4 -0
  114. package/lib/matrix.js +66 -0
  115. package/lib/matrix.js.map +1 -0
  116. package/lib/promoter/index.d.ts +65 -0
  117. package/lib/promoter/index.js +1208 -0
  118. package/lib/promoter/index.js.map +1 -0
  119. package/lib/prune/index.d.ts +37 -0
  120. package/lib/prune/index.js +673 -0
  121. package/lib/prune/index.js.map +1 -0
  122. package/lib/sets.d.ts +10 -0
  123. package/lib/sets.js +120 -0
  124. package/lib/sets.js.map +1 -0
  125. package/lib/tester/cliFormat.d.ts +8 -0
  126. package/lib/tester/cliFormat.js +15 -0
  127. package/lib/tester/cliFormat.js.map +1 -0
  128. package/lib/tester/index.d.ts +35 -0
  129. package/lib/tester/index.js +713 -0
  130. package/lib/tester/index.js.map +1 -0
  131. package/lib/tester/matrix.d.ts +14 -0
  132. package/lib/tester/matrix.js +76 -0
  133. package/lib/tester/matrix.js.map +1 -0
  134. package/lib/tester/prettyDuration.d.ts +1 -0
  135. package/lib/tester/prettyDuration.js +30 -0
  136. package/lib/tester/prettyDuration.js.map +1 -0
  137. package/lib/tester/printTestResult.d.ts +2 -0
  138. package/lib/tester/printTestResult.js +32 -0
  139. package/lib/tester/printTestResult.js.map +1 -0
  140. package/lib/tester/types.d.ts +29 -0
  141. package/lib/tester/types.js +3 -0
  142. package/lib/tester/types.js.map +1 -0
  143. package/package.json +41 -13
  144. package/src/benchmark/index.spec.ts +375 -0
  145. package/src/benchmark/index.ts +433 -0
  146. package/src/builder/index.spec.ts +822 -0
  147. package/src/builder/index.ts +920 -0
  148. package/src/cli/index.spec.ts +54 -0
  149. package/src/cli/index.ts +150 -0
  150. package/src/config/index.spec.ts +70 -0
  151. package/src/config/index.ts +259 -0
  152. package/src/create/index.spec.ts +272 -0
  153. package/src/create/index.ts +295 -0
  154. package/src/datasource/filesystemAdapter.ts +313 -0
  155. package/src/datasource/index.ts +135 -0
  156. package/src/error.ts +33 -0
  157. package/src/evaluate/cli.spec.ts +368 -0
  158. package/src/evaluate/cli.ts +130 -0
  159. package/src/evaluate/index.ts +161 -0
  160. package/src/examples/coerceExampleIsoDates.spec.ts +81 -0
  161. package/src/examples/coerceExampleIsoDates.ts +98 -0
  162. package/src/examples/index.spec.ts +453 -0
  163. package/src/examples/index.ts +854 -0
  164. package/src/exporter/index.spec.ts +443 -0
  165. package/src/exporter/index.ts +643 -0
  166. package/src/find-duplicates/index.spec.ts +289 -0
  167. package/src/find-duplicates/index.ts +314 -0
  168. package/src/generate-code/index.ts +92 -0
  169. package/src/generate-code/typescript.spec.ts +241 -0
  170. package/src/generate-code/typescript.ts +284 -0
  171. package/src/importer/index.spec.ts +1101 -0
  172. package/src/importer/index.ts +1190 -0
  173. package/src/index.ts +18 -0
  174. package/src/info/index.ts +67 -0
  175. package/src/init/index.spec.ts +279 -0
  176. package/src/init/index.ts +292 -0
  177. package/src/lint/index.ts +1 -0
  178. package/src/linter/attributeSchema.ts +38 -0
  179. package/src/linter/checkLocaleCircularDependency.ts +51 -0
  180. package/src/linter/conditionSchema.ts +386 -0
  181. package/src/linter/formatSchema.ts +170 -0
  182. package/src/linter/icuStyleLint.ts +312 -0
  183. package/src/linter/index.spec.ts +824 -0
  184. package/src/linter/index.ts +460 -0
  185. package/src/linter/localeSchema.ts +70 -0
  186. package/src/linter/messageSchema.ts +152 -0
  187. package/src/linter/printError.ts +52 -0
  188. package/src/linter/schema.ts +230 -0
  189. package/src/linter/segmentSchema.ts +15 -0
  190. package/src/linter/targetSchema.ts +50 -0
  191. package/src/linter/testSchema.spec.ts +405 -0
  192. package/src/linter/testSchema.ts +239 -0
  193. package/src/linter/zodHelpers.ts +16 -0
  194. package/src/list/index.spec.ts +431 -0
  195. package/src/list/index.ts +463 -0
  196. package/src/matrix.ts +69 -0
  197. package/src/promoter/index.spec.ts +584 -0
  198. package/src/promoter/index.ts +1267 -0
  199. package/src/prune/index.spec.ts +418 -0
  200. package/src/prune/index.ts +693 -0
  201. package/src/sets.ts +74 -0
  202. package/src/tester/cliFormat.ts +11 -0
  203. package/src/tester/featurevisorIntegration.spec.ts +101 -0
  204. package/src/tester/index.spec.ts +577 -0
  205. package/src/tester/index.ts +679 -0
  206. package/src/tester/matrix.ts +106 -0
  207. package/src/tester/prettyDuration.ts +34 -0
  208. package/src/tester/printTestResult.ts +40 -0
  209. package/src/tester/types.ts +32 -0
  210. package/tsconfig.cjs.json +11 -0
  211. package/tsconfig.typecheck.json +4 -0
@@ -0,0 +1,1208 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
17
+ desc = { enumerable: true, get: function() { return m[k]; } };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
28
+ });
29
+ var __importStar = (this && this.__importStar) || (function () {
30
+ var ownKeys = function(o) {
31
+ ownKeys = Object.getOwnPropertyNames || function (o) {
32
+ var ar = [];
33
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
34
+ return ar;
35
+ };
36
+ return ownKeys(o);
37
+ };
38
+ return function (mod) {
39
+ if (mod && mod.__esModule) return mod;
40
+ var result = {};
41
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
42
+ __setModuleDefault(result, mod);
43
+ return result;
44
+ };
45
+ })();
46
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
47
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
48
+ return new (P || (P = Promise))(function (resolve, reject) {
49
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
50
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
51
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
52
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
53
+ });
54
+ };
55
+ var __generator = (this && this.__generator) || function (thisArg, body) {
56
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
57
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
58
+ function verb(n) { return function (v) { return step([n, v]); }; }
59
+ function step(op) {
60
+ if (f) throw new TypeError("Generator is already executing.");
61
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
62
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
63
+ if (y = 0, t) op = [op[0] & 2, t.value];
64
+ switch (op[0]) {
65
+ case 0: case 1: t = op; break;
66
+ case 4: _.label++; return { value: op[1], done: false };
67
+ case 5: _.label++; y = op[1]; op = [0]; continue;
68
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
69
+ default:
70
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
71
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
72
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
73
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
74
+ if (t[2]) _.ops.pop();
75
+ _.trys.pop(); continue;
76
+ }
77
+ op = body.call(thisArg, _);
78
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
79
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
80
+ }
81
+ };
82
+ var __rest = (this && this.__rest) || function (s, e) {
83
+ var t = {};
84
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
85
+ t[p] = s[p];
86
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
87
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
88
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
89
+ t[p[i]] = s[p[i]];
90
+ }
91
+ return t;
92
+ };
93
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
94
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
95
+ if (ar || !(i in from)) {
96
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
97
+ ar[i] = from[i];
98
+ }
99
+ }
100
+ return to.concat(ar || Array.prototype.slice.call(from));
101
+ };
102
+ Object.defineProperty(exports, "__esModule", { value: true });
103
+ exports.promotePlugin = void 0;
104
+ exports.promoteProjectSets = promoteProjectSets;
105
+ /* eslint-disable @typescript-eslint/no-unused-vars */
106
+ var fs = __importStar(require("fs"));
107
+ var path = __importStar(require("path"));
108
+ var error_1 = require("../error");
109
+ var linter_1 = require("../linter");
110
+ var cliFormat_1 = require("../tester/cliFormat");
111
+ var prettyDuration_1 = require("../tester/prettyDuration");
112
+ function isPromotable(entity) {
113
+ return (entity === null || entity === void 0 ? void 0 : entity.promotable) !== false;
114
+ }
115
+ function assertAllowedPromotionFlow(projectConfig, from, to) {
116
+ var allowedFlows = projectConfig.promotionFlows;
117
+ if (typeof allowedFlows === "undefined") {
118
+ return;
119
+ }
120
+ var isAllowed = allowedFlows.some(function (flow) { return flow.from === from && flow.to === to; });
121
+ if (isAllowed) {
122
+ return;
123
+ }
124
+ var allowedList = allowedFlows.map(function (flow) { return "".concat(flow.from, " -> ").concat(flow.to); }).join(", ") || "none";
125
+ throw new error_1.MessagevisorCLIError("Promotion from \"".concat(from, "\" to \"").concat(to, "\" is not allowed by this project's configured promotionFlows.\nAllowed flows: ").concat(allowedList, ".\nChoose one of the allowed promotion paths or update messagevisor.config.js if this flow should be permitted."));
126
+ }
127
+ function toArray(value) {
128
+ if (typeof value === "undefined") {
129
+ return [];
130
+ }
131
+ return Array.isArray(value) ? value : [value];
132
+ }
133
+ function isPlainObject(value) {
134
+ return typeof value === "object" && value !== null && !Array.isArray(value);
135
+ }
136
+ function deepEqual(left, right) {
137
+ return JSON.stringify(left) === JSON.stringify(right);
138
+ }
139
+ function getArrayEntryIdentity(value) {
140
+ if (!isPlainObject(value)) {
141
+ return undefined;
142
+ }
143
+ if (typeof value.description === "string") {
144
+ return "description:".concat(value.description);
145
+ }
146
+ var identity = {};
147
+ for (var _i = 0, _a = [
148
+ "locale",
149
+ "target",
150
+ "segment",
151
+ "context",
152
+ "values",
153
+ "withFlags",
154
+ "withVariations",
155
+ "currency",
156
+ "timeZone",
157
+ ]; _i < _a.length; _i++) {
158
+ var key = _a[_i];
159
+ if (typeof value[key] !== "undefined") {
160
+ identity[key] = value[key];
161
+ }
162
+ }
163
+ return Object.keys(identity).length > 0 ? JSON.stringify(identity) : undefined;
164
+ }
165
+ function deepMerge(destination, source) {
166
+ if (typeof destination === "undefined")
167
+ return source;
168
+ if (typeof source === "undefined")
169
+ return destination;
170
+ if (Array.isArray(destination) && Array.isArray(source)) {
171
+ var result = __spreadArray([], source, true);
172
+ var sourceIdentities = new Set(source.map(getArrayEntryIdentity).filter(function (value) { return Boolean(value); }));
173
+ var _loop_1 = function (entry) {
174
+ var identity = getArrayEntryIdentity(entry);
175
+ if (!identity && !result.some(function (item) { return deepEqual(item, entry); })) {
176
+ result.push(entry);
177
+ }
178
+ else if (identity &&
179
+ !sourceIdentities.has(identity) &&
180
+ !result.some(function (item) { return getArrayEntryIdentity(item) === identity; })) {
181
+ result.push(entry);
182
+ }
183
+ };
184
+ for (var _i = 0, destination_1 = destination; _i < destination_1.length; _i++) {
185
+ var entry = destination_1[_i];
186
+ _loop_1(entry);
187
+ }
188
+ return result;
189
+ }
190
+ if (isPlainObject(destination) && isPlainObject(source)) {
191
+ var result = __assign({}, destination);
192
+ for (var _a = 0, _b = Object.keys(source); _a < _b.length; _a++) {
193
+ var key = _b[_a];
194
+ result[key] = deepMerge(result[key], source[key]);
195
+ }
196
+ return result;
197
+ }
198
+ return source;
199
+ }
200
+ function deepMergeWithPolicy(destination, source, policy, conflicts, pathSegments) {
201
+ if (pathSegments === void 0) { pathSegments = []; }
202
+ if (typeof destination === "undefined")
203
+ return source;
204
+ if (typeof source === "undefined")
205
+ return destination;
206
+ var conflictPath = pathSegments.join(".") || "<root>";
207
+ if (Array.isArray(destination) && Array.isArray(source)) {
208
+ if (!deepEqual(destination, source)) {
209
+ conflicts.push({ path: conflictPath, source: source, destination: destination });
210
+ }
211
+ if (policy === "destination") {
212
+ var result = __spreadArray([], destination, true);
213
+ var destinationIdentities = new Set(destination.map(getArrayEntryIdentity).filter(function (value) { return Boolean(value); }));
214
+ var _loop_2 = function (entry) {
215
+ var identity = getArrayEntryIdentity(entry);
216
+ if (!identity && !result.some(function (item) { return deepEqual(item, entry); })) {
217
+ result.push(entry);
218
+ }
219
+ else if (identity &&
220
+ !destinationIdentities.has(identity) &&
221
+ !result.some(function (item) { return getArrayEntryIdentity(item) === identity; })) {
222
+ result.push(entry);
223
+ }
224
+ };
225
+ for (var _i = 0, source_1 = source; _i < source_1.length; _i++) {
226
+ var entry = source_1[_i];
227
+ _loop_2(entry);
228
+ }
229
+ return result;
230
+ }
231
+ return deepMerge(destination, source);
232
+ }
233
+ if (isPlainObject(destination) && isPlainObject(source)) {
234
+ var result = __assign({}, destination);
235
+ for (var _a = 0, _b = Object.keys(source); _a < _b.length; _a++) {
236
+ var key = _b[_a];
237
+ result[key] = deepMergeWithPolicy(result[key], source[key], policy, conflicts, __spreadArray(__spreadArray([], pathSegments, true), [
238
+ key,
239
+ ], false));
240
+ }
241
+ return result;
242
+ }
243
+ if (!deepEqual(destination, source)) {
244
+ conflicts.push({ path: conflictPath, source: source, destination: destination });
245
+ }
246
+ return policy === "destination" ? destination : source;
247
+ }
248
+ function matchesPattern(key, patterns) {
249
+ if (patterns.length === 0) {
250
+ return false;
251
+ }
252
+ return patterns.some(function (pattern) {
253
+ var escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
254
+ return new RegExp("^".concat(escaped, "$")).test(key);
255
+ });
256
+ }
257
+ function withoutKey(entity) {
258
+ var _key = entity.key, rest = __rest(entity, ["key"]);
259
+ return rest;
260
+ }
261
+ function filterLocaleMap(values, locales) {
262
+ if (!values || locales.size === 0) {
263
+ return values;
264
+ }
265
+ return Object.fromEntries(Object.entries(values).filter(function (_a) {
266
+ var locale = _a[0];
267
+ return locales.has(locale);
268
+ }));
269
+ }
270
+ function collectGroupSegmentKeys(value, result) {
271
+ if (!value || value === "*")
272
+ return;
273
+ if (typeof value === "string") {
274
+ result.add(value);
275
+ return;
276
+ }
277
+ if (Array.isArray(value)) {
278
+ value.forEach(function (entry) { return collectGroupSegmentKeys(entry, result); });
279
+ return;
280
+ }
281
+ if (value.and)
282
+ value.and.forEach(function (entry) { return collectGroupSegmentKeys(entry, result); });
283
+ if (value.or)
284
+ value.or.forEach(function (entry) { return collectGroupSegmentKeys(entry, result); });
285
+ if (value.not)
286
+ value.not.forEach(function (entry) { return collectGroupSegmentKeys(entry, result); });
287
+ }
288
+ function collectConditionDependencies(value, segments, attributes) {
289
+ if (!value || value === "*")
290
+ return;
291
+ if (typeof value === "string") {
292
+ segments.add(value);
293
+ return;
294
+ }
295
+ if (Array.isArray(value)) {
296
+ value.forEach(function (entry) { return collectConditionDependencies(entry, segments, attributes); });
297
+ return;
298
+ }
299
+ if ("attribute" in value) {
300
+ attributes.add(value.attribute.split(".")[0]);
301
+ return;
302
+ }
303
+ if ("and" in value)
304
+ value.and.forEach(function (entry) { return collectConditionDependencies(entry, segments, attributes); });
305
+ if ("or" in value)
306
+ value.or.forEach(function (entry) { return collectConditionDependencies(entry, segments, attributes); });
307
+ if ("not" in value)
308
+ value.not.forEach(function (entry) { return collectConditionDependencies(entry, segments, attributes); });
309
+ }
310
+ function mergeMessage(messageKey, destination, source, policy, conflicts) {
311
+ if (!destination) {
312
+ return source;
313
+ }
314
+ validateMessageOverrideKeys(messageKey, destination);
315
+ var sourceOverrides = source.overrides || [];
316
+ var destinationOverrides = destination.overrides || [];
317
+ var mergedOverrideKeys = new Set();
318
+ var overrides = sourceOverrides.map(function (sourceOverride) {
319
+ var destinationOverride = destinationOverrides.find(function (override) { return override.key === sourceOverride.key; });
320
+ mergedOverrideKeys.add(sourceOverride.key);
321
+ var overrideConflicts = [];
322
+ var merged = deepMergeWithPolicy(destinationOverride, sourceOverride, policy, overrideConflicts, ["overrides", sourceOverride.key]);
323
+ conflicts.push.apply(conflicts, overrideConflicts.map(function (conflict) { return (__assign({ type: "message", key: messageKey }, conflict)); }));
324
+ return merged;
325
+ });
326
+ for (var _i = 0, destinationOverrides_1 = destinationOverrides; _i < destinationOverrides_1.length; _i++) {
327
+ var destinationOverride = destinationOverrides_1[_i];
328
+ if (!mergedOverrideKeys.has(destinationOverride.key)) {
329
+ overrides.push(destinationOverride);
330
+ }
331
+ }
332
+ var messageConflicts = [];
333
+ var mergedMessage = deepMergeWithPolicy(destination, __assign(__assign({}, source), { overrides: undefined }), policy, messageConflicts);
334
+ conflicts.push.apply(conflicts, messageConflicts.map(function (conflict) { return (__assign({ type: "message", key: messageKey }, conflict)); }));
335
+ return __assign(__assign({}, mergedMessage), { overrides: overrides.length > 0 ? overrides : undefined });
336
+ }
337
+ function removeMessageOverrides(message) {
338
+ var _overrides = message.overrides, messageWithoutOverrides = __rest(message, ["overrides"]);
339
+ return messageWithoutOverrides;
340
+ }
341
+ function filterMessageForLocales(message, locales) {
342
+ if (locales.size === 0) {
343
+ return message;
344
+ }
345
+ var overrides = (message.overrides || [])
346
+ .map(function (override) { return (__assign(__assign({}, override), { translations: filterLocaleMap(override.translations, locales) || {} })); })
347
+ .filter(function (override) { return Object.keys(override.translations).length > 0; });
348
+ return __assign(__assign({}, message), { translations: filterLocaleMap(message.translations, locales) || {}, overrides: overrides.length > 0 ? overrides : undefined });
349
+ }
350
+ function filterTargetForLocales(target, locales) {
351
+ var _a;
352
+ if (locales.size === 0) {
353
+ return target;
354
+ }
355
+ return __assign(__assign({}, target), { locales: (_a = target.locales) === null || _a === void 0 ? void 0 : _a.filter(function (locale) { return locales.has(locale); }), formats: filterLocaleMap(target.formats, locales) });
356
+ }
357
+ function filterTestForLocales(test, locales) {
358
+ if (locales.size === 0 || !Array.isArray(test.assertions)) {
359
+ return test;
360
+ }
361
+ return __assign(__assign({}, test), { assertions: test.assertions.filter(function (assertion) { return !assertion.locale || locales.has(assertion.locale); }) });
362
+ }
363
+ function validateMessageOverrideKeys(messageKey, message) {
364
+ var keys = new Set();
365
+ for (var index = 0; index < (message.overrides || []).length; index++) {
366
+ var override = (message.overrides || [])[index];
367
+ if (!override.key) {
368
+ throw new Error("Message \"".concat(messageKey, "\" override at index ").concat(index, " must define a key before promotion."));
369
+ }
370
+ if (keys.has(override.key)) {
371
+ throw new Error("Message \"".concat(messageKey, "\" has duplicate override key \"").concat(override.key, "\"."));
372
+ }
373
+ keys.add(override.key);
374
+ }
375
+ }
376
+ function safeRead(keys, read) {
377
+ return __awaiter(this, void 0, void 0, function () {
378
+ var entries;
379
+ var _this = this;
380
+ return __generator(this, function (_a) {
381
+ switch (_a.label) {
382
+ case 0: return [4 /*yield*/, Promise.all(keys.map(function (key) { return __awaiter(_this, void 0, void 0, function () { var _a; return __generator(this, function (_b) {
383
+ switch (_b.label) {
384
+ case 0:
385
+ _a = [key];
386
+ return [4 /*yield*/, read(key)];
387
+ case 1: return [2 /*return*/, _a.concat([_b.sent()])];
388
+ }
389
+ }); }); }))];
390
+ case 1:
391
+ entries = _a.sent();
392
+ return [2 /*return*/, Object.fromEntries(entries)];
393
+ }
394
+ });
395
+ });
396
+ }
397
+ function readDestination(key, read) {
398
+ return __awaiter(this, void 0, void 0, function () {
399
+ var _a;
400
+ return __generator(this, function (_b) {
401
+ switch (_b.label) {
402
+ case 0:
403
+ _b.trys.push([0, 2, , 3]);
404
+ return [4 /*yield*/, read(key)];
405
+ case 1: return [2 /*return*/, _b.sent()];
406
+ case 2:
407
+ _a = _b.sent();
408
+ return [2 /*return*/, undefined];
409
+ case 3: return [2 /*return*/];
410
+ }
411
+ });
412
+ });
413
+ }
414
+ function formatLintPreflightErrors(set, errors) {
415
+ var preview = errors
416
+ .slice(0, 5)
417
+ .map(function (error) { return "".concat(error.filePath, ": ").concat(error.message); })
418
+ .join("\n");
419
+ var suffix = errors.length > 5 ? "\n...and ".concat(errors.length - 5, " more") : "";
420
+ return "Set \"".concat(set, "\" failed preflight lint with ").concat(errors.length, " error(s).\n").concat(preview).concat(suffix);
421
+ }
422
+ function assertSetLintsClean(set, datasource) {
423
+ return __awaiter(this, void 0, void 0, function () {
424
+ var result;
425
+ return __generator(this, function (_a) {
426
+ switch (_a.label) {
427
+ case 0: return [4 /*yield*/, (0, linter_1.lintProject)(datasource.getConfig(), datasource)];
428
+ case 1:
429
+ result = _a.sent();
430
+ if (result.hasError) {
431
+ throw new Error(formatLintPreflightErrors(set, result.errors));
432
+ }
433
+ return [2 /*return*/];
434
+ }
435
+ });
436
+ });
437
+ }
438
+ function getEntityFilePath(projectConfig, type, key) {
439
+ var directories = {
440
+ locale: projectConfig.localesDirectoryPath,
441
+ attribute: projectConfig.attributesDirectoryPath,
442
+ segment: projectConfig.segmentsDirectoryPath,
443
+ target: projectConfig.targetsDirectoryPath,
444
+ message: projectConfig.messagesDirectoryPath,
445
+ test: projectConfig.testsDirectoryPath,
446
+ };
447
+ var extension = projectConfig.parser.extension || "yml";
448
+ return (path.join.apply(path, __spreadArray([directories[type]], key.split(projectConfig.namespaceCharacter), false)) + ".".concat(extension));
449
+ }
450
+ function getPromotionPlan(sourceDatasource, destinationDatasource, options) {
451
+ return __awaiter(this, void 0, void 0, function () {
452
+ function addLocaleWithAncestors(locale, result) {
453
+ if (!locales[locale] || result.has(locale))
454
+ return;
455
+ result.add(locale);
456
+ if (locales[locale].inheritFormatsFrom)
457
+ addLocaleWithAncestors(locales[locale].inheritFormatsFrom, result);
458
+ if (locales[locale].inheritTranslationsFrom)
459
+ addLocaleWithAncestors(locales[locale].inheritTranslationsFrom, result);
460
+ }
461
+ function plan(type_1, key_1, source_2, readDestinationEntity_1) {
462
+ return __awaiter(this, arguments, void 0, function (type, key, source, readDestinationEntity, merge) {
463
+ var cleanedSource, destination, cleanedDestination, conflicts, merged;
464
+ if (merge === void 0) { merge = function (destination, sourceValue, conflicts) {
465
+ var entityConflicts = [];
466
+ var merged = deepMergeWithPolicy(destination, sourceValue, options.conflicts, entityConflicts);
467
+ conflicts.push.apply(conflicts, entityConflicts.map(function (conflict) { return (__assign({ type: type, key: key }, conflict)); }));
468
+ return merged;
469
+ }; }
470
+ return __generator(this, function (_a) {
471
+ switch (_a.label) {
472
+ case 0:
473
+ cleanedSource = withoutKey(source);
474
+ return [4 /*yield*/, readDestination(key, readDestinationEntity)];
475
+ case 1:
476
+ destination = _a.sent();
477
+ cleanedDestination = destination ? withoutKey(destination) : undefined;
478
+ if (cleanedDestination && (!isPromotable(cleanedSource) || !isPromotable(cleanedDestination))) {
479
+ plans.push({
480
+ type: type,
481
+ key: key,
482
+ source: cleanedSource,
483
+ destination: cleanedDestination,
484
+ merged: cleanedDestination,
485
+ conflicts: [],
486
+ });
487
+ return [2 /*return*/];
488
+ }
489
+ conflicts = [];
490
+ merged = merge(cleanedDestination, cleanedSource, conflicts);
491
+ plans.push({
492
+ type: type,
493
+ key: key,
494
+ source: cleanedSource,
495
+ destination: cleanedDestination,
496
+ merged: merged,
497
+ conflicts: conflicts,
498
+ });
499
+ return [2 /*return*/];
500
+ }
501
+ });
502
+ });
503
+ }
504
+ var selectedTargets, requestedLocales, includeMessages, excludeMessages, hasNoFilters, _a, localeKeys, targetKeys, messageKeys, segmentKeys, attributeKeys, testKeys, _i, _b, locale, _c, locales, targets, messages, segments, attributes, tests, promotedTargetKeys, promotedMessageKeys, explicitRuntimeLocales, matchedMessageCount, _d, messageKeys_1, messageKey, _e, _f, messageKey, _g, _h, messageKey, message, _j, _k, override, promotedLocaleKeys, localeFilterKeys, localeRestricted, localeSeeds, promotedSegmentKeys, promotedAttributeKeys, _l, _m, messageKey, message, _o, _p, override, pendingSegments, index, segmentKey, segment, beforeSize, promotedTestKeys, plans, _q, _r, key, _s, _t, key, _u, _v, key, targetLocaleFilter, _w, _x, key, messageLocaleFilter, _loop_3, _y, _z, key, _0, _1, key, test_1;
505
+ return __generator(this, function (_2) {
506
+ switch (_2.label) {
507
+ case 0:
508
+ selectedTargets = new Set(toArray(options.target));
509
+ requestedLocales = new Set(toArray(options.locale));
510
+ includeMessages = toArray(options.includeMessages);
511
+ excludeMessages = toArray(options.excludeMessages);
512
+ hasNoFilters = selectedTargets.size === 0 && includeMessages.length === 0 && requestedLocales.size === 0;
513
+ return [4 /*yield*/, Promise.all([
514
+ sourceDatasource.listLocales(),
515
+ sourceDatasource.listTargets(),
516
+ sourceDatasource.listMessages(),
517
+ sourceDatasource.listSegments(),
518
+ sourceDatasource.listAttributes(),
519
+ sourceDatasource.listTests(),
520
+ ])];
521
+ case 1:
522
+ _a = _2.sent(), localeKeys = _a[0], targetKeys = _a[1], messageKeys = _a[2], segmentKeys = _a[3], attributeKeys = _a[4], testKeys = _a[5];
523
+ for (_i = 0, _b = Array.from(requestedLocales); _i < _b.length; _i++) {
524
+ locale = _b[_i];
525
+ if (!localeKeys.includes(locale)) {
526
+ throw new Error("Unknown source locale \"".concat(locale, "\". Available locales: ").concat(localeKeys.join(", ") || "none", "."));
527
+ }
528
+ }
529
+ return [4 /*yield*/, Promise.all([
530
+ safeRead(localeKeys, function (key) { return sourceDatasource.readLocale(key); }),
531
+ safeRead(targetKeys, function (key) { return sourceDatasource.readTarget(key); }),
532
+ safeRead(messageKeys, function (key) { return sourceDatasource.readMessage(key); }),
533
+ safeRead(segmentKeys, function (key) { return sourceDatasource.readSegment(key); }),
534
+ safeRead(attributeKeys, function (key) { return sourceDatasource.readAttribute(key); }),
535
+ safeRead(testKeys, function (key) { return sourceDatasource.readTest(key); }),
536
+ ])];
537
+ case 2:
538
+ _c = _2.sent(), locales = _c[0], targets = _c[1], messages = _c[2], segments = _c[3], attributes = _c[4], tests = _c[5];
539
+ promotedTargetKeys = new Set();
540
+ promotedMessageKeys = new Set();
541
+ explicitRuntimeLocales = new Set();
542
+ if (hasNoFilters) {
543
+ targetKeys.forEach(function (key) { return promotedTargetKeys.add(key); });
544
+ messageKeys.forEach(function (key) { return promotedMessageKeys.add(key); });
545
+ localeKeys.forEach(function (key) { return explicitRuntimeLocales.add(key); });
546
+ }
547
+ else {
548
+ selectedTargets.forEach(function (key) {
549
+ var _a;
550
+ if (!targets[key])
551
+ throw new Error("Unknown source target \"".concat(key, "\"."));
552
+ promotedTargetKeys.add(key);
553
+ (targets[key].locales || localeKeys).forEach(function (locale) { return explicitRuntimeLocales.add(locale); });
554
+ for (var _i = 0, messageKeys_2 = messageKeys; _i < messageKeys_2.length; _i++) {
555
+ var messageKey = messageKeys_2[_i];
556
+ var included = matchesPattern(messageKey, ((_a = targets[key].includeMessages) === null || _a === void 0 ? void 0 : _a.length) ? targets[key].includeMessages : ["*"]);
557
+ var excluded = matchesPattern(messageKey, targets[key].excludeMessages || []);
558
+ if (included && !excluded) {
559
+ promotedMessageKeys.add(messageKey);
560
+ }
561
+ }
562
+ });
563
+ if (includeMessages.length > 0) {
564
+ matchedMessageCount = 0;
565
+ for (_d = 0, messageKeys_1 = messageKeys; _d < messageKeys_1.length; _d++) {
566
+ messageKey = messageKeys_1[_d];
567
+ if (matchesPattern(messageKey, includeMessages) &&
568
+ !matchesPattern(messageKey, excludeMessages)) {
569
+ promotedMessageKeys.add(messageKey);
570
+ matchedMessageCount++;
571
+ }
572
+ }
573
+ if (matchedMessageCount === 0 && !options.allowEmpty) {
574
+ throw new Error("No source messages matched --includeMessages=".concat(includeMessages.join(", "), "."));
575
+ }
576
+ }
577
+ if (requestedLocales.size > 0) {
578
+ requestedLocales.forEach(function (locale) { return explicitRuntimeLocales.add(locale); });
579
+ if (selectedTargets.size === 0 && includeMessages.length === 0) {
580
+ targetKeys.forEach(function (key) { return promotedTargetKeys.add(key); });
581
+ messageKeys.forEach(function (key) { return promotedMessageKeys.add(key); });
582
+ }
583
+ }
584
+ }
585
+ for (_e = 0, _f = Array.from(promotedMessageKeys); _e < _f.length; _e++) {
586
+ messageKey = _f[_e];
587
+ if (matchesPattern(messageKey, excludeMessages)) {
588
+ promotedMessageKeys.delete(messageKey);
589
+ }
590
+ }
591
+ if (selectedTargets.size === 0 && requestedLocales.size === 0 && includeMessages.length > 0) {
592
+ for (_g = 0, _h = Array.from(promotedMessageKeys); _g < _h.length; _g++) {
593
+ messageKey = _h[_g];
594
+ message = messages[messageKey];
595
+ if (!message)
596
+ continue;
597
+ Object.keys(message.translations || {}).forEach(function (locale) {
598
+ return explicitRuntimeLocales.add(locale);
599
+ });
600
+ if (!options.excludeOverrides) {
601
+ for (_j = 0, _k = message.overrides || []; _j < _k.length; _j++) {
602
+ override = _k[_j];
603
+ Object.keys(override.translations || {}).forEach(function (locale) {
604
+ return explicitRuntimeLocales.add(locale);
605
+ });
606
+ }
607
+ }
608
+ }
609
+ }
610
+ promotedLocaleKeys = new Set();
611
+ localeFilterKeys = new Set();
612
+ localeRestricted = requestedLocales.size > 0 || selectedTargets.size > 0;
613
+ localeSeeds = requestedLocales.size > 0 ? requestedLocales : explicitRuntimeLocales;
614
+ localeSeeds.forEach(function (locale) { return addLocaleWithAncestors(locale, promotedLocaleKeys); });
615
+ (requestedLocales.size > 0 ? requestedLocales : new Set()).forEach(function (locale) {
616
+ return addLocaleWithAncestors(locale, localeFilterKeys);
617
+ });
618
+ if (hasNoFilters && !localeRestricted && promotedLocaleKeys.size === 0) {
619
+ localeKeys.forEach(function (key) { return promotedLocaleKeys.add(key); });
620
+ }
621
+ promotedSegmentKeys = new Set();
622
+ promotedAttributeKeys = new Set();
623
+ for (_l = 0, _m = Array.from(promotedMessageKeys); _l < _m.length; _l++) {
624
+ messageKey = _m[_l];
625
+ message = messages[messageKey];
626
+ if (!message)
627
+ continue;
628
+ if (!options.excludeOverrides) {
629
+ validateMessageOverrideKeys(messageKey, message);
630
+ for (_o = 0, _p = message.overrides || []; _o < _p.length; _o++) {
631
+ override = _p[_o];
632
+ collectConditionDependencies(override.conditions, promotedSegmentKeys, promotedAttributeKeys);
633
+ collectGroupSegmentKeys(override.segments, promotedSegmentKeys);
634
+ }
635
+ }
636
+ }
637
+ pendingSegments = Array.from(promotedSegmentKeys);
638
+ for (index = 0; index < pendingSegments.length; index++) {
639
+ segmentKey = pendingSegments[index];
640
+ segment = segments[segmentKey];
641
+ if (!segment)
642
+ continue;
643
+ beforeSize = promotedSegmentKeys.size;
644
+ collectConditionDependencies(segment.conditions, promotedSegmentKeys, promotedAttributeKeys);
645
+ if (promotedSegmentKeys.size > beforeSize) {
646
+ pendingSegments.push.apply(pendingSegments, Array.from(promotedSegmentKeys).filter(function (key) { return !pendingSegments.includes(key); }));
647
+ }
648
+ }
649
+ if (hasNoFilters) {
650
+ segmentKeys.forEach(function (key) { return promotedSegmentKeys.add(key); });
651
+ attributeKeys.forEach(function (key) { return promotedAttributeKeys.add(key); });
652
+ }
653
+ promotedTestKeys = testKeys.filter(function (key) {
654
+ var test = tests[key];
655
+ return (promotedMessageKeys.has(test.message) ||
656
+ promotedSegmentKeys.has(test.segment) ||
657
+ promotedTargetKeys.has(test.target) ||
658
+ promotedLocaleKeys.has(test.locale));
659
+ });
660
+ plans = [];
661
+ _q = 0, _r = Array.from(promotedLocaleKeys).sort();
662
+ _2.label = 3;
663
+ case 3:
664
+ if (!(_q < _r.length)) return [3 /*break*/, 6];
665
+ key = _r[_q];
666
+ if (!locales[key]) return [3 /*break*/, 5];
667
+ return [4 /*yield*/, plan("locale", key, locales[key], function (entryKey) {
668
+ return destinationDatasource.readLocale(entryKey);
669
+ })];
670
+ case 4:
671
+ _2.sent();
672
+ _2.label = 5;
673
+ case 5:
674
+ _q++;
675
+ return [3 /*break*/, 3];
676
+ case 6:
677
+ _s = 0, _t = Array.from(promotedAttributeKeys).sort();
678
+ _2.label = 7;
679
+ case 7:
680
+ if (!(_s < _t.length)) return [3 /*break*/, 10];
681
+ key = _t[_s];
682
+ if (!attributes[key]) return [3 /*break*/, 9];
683
+ return [4 /*yield*/, plan("attribute", key, attributes[key], function (entryKey) {
684
+ return destinationDatasource.readAttribute(entryKey);
685
+ })];
686
+ case 8:
687
+ _2.sent();
688
+ _2.label = 9;
689
+ case 9:
690
+ _s++;
691
+ return [3 /*break*/, 7];
692
+ case 10:
693
+ _u = 0, _v = Array.from(promotedSegmentKeys).sort();
694
+ _2.label = 11;
695
+ case 11:
696
+ if (!(_u < _v.length)) return [3 /*break*/, 14];
697
+ key = _v[_u];
698
+ if (!segments[key]) return [3 /*break*/, 13];
699
+ return [4 /*yield*/, plan("segment", key, segments[key], function (entryKey) {
700
+ return destinationDatasource.readSegment(entryKey);
701
+ })];
702
+ case 12:
703
+ _2.sent();
704
+ _2.label = 13;
705
+ case 13:
706
+ _u++;
707
+ return [3 /*break*/, 11];
708
+ case 14:
709
+ targetLocaleFilter = requestedLocales.size > 0 ? new Set(Array.from(requestedLocales)) : new Set();
710
+ _w = 0, _x = Array.from(promotedTargetKeys).sort();
711
+ _2.label = 15;
712
+ case 15:
713
+ if (!(_w < _x.length)) return [3 /*break*/, 18];
714
+ key = _x[_w];
715
+ if (!targets[key]) return [3 /*break*/, 17];
716
+ return [4 /*yield*/, plan("target", key, filterTargetForLocales(targets[key], targetLocaleFilter), function (entryKey) { return destinationDatasource.readTarget(entryKey); })];
717
+ case 16:
718
+ _2.sent();
719
+ _2.label = 17;
720
+ case 17:
721
+ _w++;
722
+ return [3 /*break*/, 15];
723
+ case 18:
724
+ messageLocaleFilter = localeFilterKeys.size > 0 ? localeFilterKeys : new Set();
725
+ _loop_3 = function (key) {
726
+ var sourceMessage;
727
+ return __generator(this, function (_3) {
728
+ switch (_3.label) {
729
+ case 0:
730
+ if (!messages[key]) return [3 /*break*/, 2];
731
+ sourceMessage = options.excludeOverrides
732
+ ? removeMessageOverrides(filterMessageForLocales(messages[key], messageLocaleFilter))
733
+ : filterMessageForLocales(messages[key], messageLocaleFilter);
734
+ return [4 /*yield*/, plan("message", key, sourceMessage, function (entryKey) { return destinationDatasource.readMessage(entryKey); }, function (destination, source, conflicts) {
735
+ return mergeMessage(key, destination, source, options.conflicts, conflicts);
736
+ })];
737
+ case 1:
738
+ _3.sent();
739
+ _3.label = 2;
740
+ case 2: return [2 /*return*/];
741
+ }
742
+ });
743
+ };
744
+ _y = 0, _z = Array.from(promotedMessageKeys).sort();
745
+ _2.label = 19;
746
+ case 19:
747
+ if (!(_y < _z.length)) return [3 /*break*/, 22];
748
+ key = _z[_y];
749
+ return [5 /*yield**/, _loop_3(key)];
750
+ case 20:
751
+ _2.sent();
752
+ _2.label = 21;
753
+ case 21:
754
+ _y++;
755
+ return [3 /*break*/, 19];
756
+ case 22:
757
+ _0 = 0, _1 = promotedTestKeys.sort();
758
+ _2.label = 23;
759
+ case 23:
760
+ if (!(_0 < _1.length)) return [3 /*break*/, 26];
761
+ key = _1[_0];
762
+ test_1 = filterTestForLocales(tests[key], requestedLocales);
763
+ if (!(!Array.isArray(test_1.assertions) || test_1.assertions.length > 0)) return [3 /*break*/, 25];
764
+ return [4 /*yield*/, plan("test", key, test_1, function (entryKey) { return destinationDatasource.readTest(entryKey); })];
765
+ case 24:
766
+ _2.sent();
767
+ _2.label = 25;
768
+ case 25:
769
+ _0++;
770
+ return [3 /*break*/, 23];
771
+ case 26: return [2 /*return*/, plans];
772
+ }
773
+ });
774
+ });
775
+ }
776
+ function writePlan(destinationDatasource, plans) {
777
+ return __awaiter(this, void 0, void 0, function () {
778
+ var _i, plans_1, plan;
779
+ return __generator(this, function (_a) {
780
+ switch (_a.label) {
781
+ case 0:
782
+ _i = 0, plans_1 = plans;
783
+ _a.label = 1;
784
+ case 1:
785
+ if (!(_i < plans_1.length)) return [3 /*break*/, 14];
786
+ plan = plans_1[_i];
787
+ if (deepEqual(plan.destination, plan.merged)) {
788
+ return [3 /*break*/, 13];
789
+ }
790
+ if (!(plan.type === "locale")) return [3 /*break*/, 3];
791
+ return [4 /*yield*/, destinationDatasource.writeLocale(plan.key, plan.merged)];
792
+ case 2:
793
+ _a.sent();
794
+ _a.label = 3;
795
+ case 3:
796
+ if (!(plan.type === "attribute")) return [3 /*break*/, 5];
797
+ return [4 /*yield*/, destinationDatasource.writeAttribute(plan.key, plan.merged)];
798
+ case 4:
799
+ _a.sent();
800
+ _a.label = 5;
801
+ case 5:
802
+ if (!(plan.type === "segment")) return [3 /*break*/, 7];
803
+ return [4 /*yield*/, destinationDatasource.writeSegment(plan.key, plan.merged)];
804
+ case 6:
805
+ _a.sent();
806
+ _a.label = 7;
807
+ case 7:
808
+ if (!(plan.type === "target")) return [3 /*break*/, 9];
809
+ return [4 /*yield*/, destinationDatasource.writeTarget(plan.key, plan.merged)];
810
+ case 8:
811
+ _a.sent();
812
+ _a.label = 9;
813
+ case 9:
814
+ if (!(plan.type === "message")) return [3 /*break*/, 11];
815
+ return [4 /*yield*/, destinationDatasource.writeMessage(plan.key, plan.merged)];
816
+ case 10:
817
+ _a.sent();
818
+ _a.label = 11;
819
+ case 11:
820
+ if (!(plan.type === "test")) return [3 /*break*/, 13];
821
+ return [4 /*yield*/, destinationDatasource.writeTest(plan.key, plan.merged)];
822
+ case 12:
823
+ _a.sent();
824
+ _a.label = 13;
825
+ case 13:
826
+ _i++;
827
+ return [3 /*break*/, 1];
828
+ case 14: return [2 /*return*/];
829
+ }
830
+ });
831
+ });
832
+ }
833
+ function normalizeConflictPolicy(value) {
834
+ if (typeof value === "undefined" || value === false) {
835
+ return "source";
836
+ }
837
+ if (value === "source" || value === "destination" || value === "fail") {
838
+ return value;
839
+ }
840
+ throw new error_1.MessagevisorCLIError("Invalid --conflicts value \"".concat(String(value), "\". Use source, destination, or fail."));
841
+ }
842
+ function normalizeAuditFormat(value) {
843
+ if (typeof value === "undefined" || value === false || value === "false") {
844
+ return false;
845
+ }
846
+ if (value === true || value === "true") {
847
+ return "json";
848
+ }
849
+ if (value === "json" || value === "markdown") {
850
+ return value;
851
+ }
852
+ throw new error_1.MessagevisorCLIError("Invalid --audit value \"".concat(String(value), "\". Use json or markdown."));
853
+ }
854
+ function getTimestamp() {
855
+ var date = new Date();
856
+ var pad = function (value) { return (value < 10 ? "0".concat(value) : String(value)); };
857
+ return [
858
+ date.getUTCFullYear(),
859
+ pad(date.getUTCMonth() + 1),
860
+ pad(date.getUTCDate()),
861
+ "T",
862
+ pad(date.getUTCHours()),
863
+ pad(date.getUTCMinutes()),
864
+ pad(date.getUTCSeconds()),
865
+ ].join("");
866
+ }
867
+ function getPromotionAuditFilePath(projectConfig, result, format) {
868
+ return __awaiter(this, void 0, void 0, function () {
869
+ var extension, baseFileName, directoryPath, suffix, fileName, filePath;
870
+ return __generator(this, function (_a) {
871
+ extension = format === "markdown" ? "md" : "json";
872
+ baseFileName = "".concat(getTimestamp(), "-").concat(result.from, "-to-").concat(result.to);
873
+ directoryPath = path.join(projectConfig.stateDirectoryPath, "promotions");
874
+ suffix = 0;
875
+ while (true) {
876
+ fileName = "".concat(baseFileName).concat(suffix === 0 ? "" : "-".concat(suffix), ".").concat(extension);
877
+ filePath = path.join(directoryPath, fileName);
878
+ if (!fs.existsSync(filePath)) {
879
+ return [2 /*return*/, filePath];
880
+ }
881
+ suffix++;
882
+ }
883
+ return [2 /*return*/];
884
+ });
885
+ });
886
+ }
887
+ function getAuditPayload(result) {
888
+ return {
889
+ from: result.from,
890
+ to: result.to,
891
+ apply: result.apply,
892
+ filters: result.filters,
893
+ dependencies: result.dependencies,
894
+ files: result.files,
895
+ conflicts: result.conflicts.map(function (conflict) { return ({
896
+ type: conflict.type,
897
+ key: conflict.key,
898
+ path: conflict.path,
899
+ source: conflict.source,
900
+ destination: conflict.destination,
901
+ }); }),
902
+ duration: result.duration,
903
+ };
904
+ }
905
+ function stringifyMarkdownAudit(result) {
906
+ var lines = [
907
+ "# Messagevisor Promotion",
908
+ "",
909
+ "- From: ".concat(result.from),
910
+ "- To: ".concat(result.to),
911
+ "- Mode: ".concat(result.apply ? "apply" : "preview"),
912
+ "- Conflicts: ".concat(result.filters.conflicts),
913
+ "- Exclude overrides: ".concat(result.filters.excludeOverrides ? "true" : "false"),
914
+ "- Duration: ".concat((0, prettyDuration_1.prettyDuration)(result.duration)),
915
+ "",
916
+ "## Dependencies",
917
+ "",
918
+ "- Locales: ".concat(result.dependencies.locales),
919
+ "- Attributes: ".concat(result.dependencies.attributes),
920
+ "- Segments: ".concat(result.dependencies.segments),
921
+ "- Targets: ".concat(result.dependencies.targets),
922
+ "- Messages: ".concat(result.dependencies.messages),
923
+ "- Tests: ".concat(result.dependencies.tests),
924
+ "",
925
+ "## Files",
926
+ "",
927
+ ];
928
+ for (var _i = 0, _a = [
929
+ ["Created", result.files.created],
930
+ ["Updated", result.files.updated],
931
+ ["Unchanged", result.files.unchanged],
932
+ ]; _i < _a.length; _i++) {
933
+ var _b = _a[_i], label = _b[0], files = _b[1];
934
+ lines.push("### ".concat(label), "");
935
+ lines.push.apply(lines, (files.length > 0 ? files.map(function (filePath) { return "- ".concat(filePath); }) : ["- None"]));
936
+ lines.push("");
937
+ }
938
+ if (result.conflicts.length > 0) {
939
+ lines.push("## Conflicts", "");
940
+ lines.push.apply(lines, result.conflicts.map(function (conflict) { return "- ".concat(conflict.type, " ").concat(conflict.key, " at ").concat(conflict.path); }));
941
+ lines.push("");
942
+ }
943
+ return "".concat(lines.join("\n"), "\n");
944
+ }
945
+ function writePromotionAudit(projectConfig, result, format) {
946
+ return __awaiter(this, void 0, void 0, function () {
947
+ var filePath, content;
948
+ return __generator(this, function (_a) {
949
+ switch (_a.label) {
950
+ case 0: return [4 /*yield*/, getPromotionAuditFilePath(projectConfig, result, format)];
951
+ case 1:
952
+ filePath = _a.sent();
953
+ return [4 /*yield*/, fs.promises.mkdir(path.dirname(filePath), { recursive: true })];
954
+ case 2:
955
+ _a.sent();
956
+ content = format === "markdown"
957
+ ? stringifyMarkdownAudit(result)
958
+ : "".concat(JSON.stringify(getAuditPayload(result), null, 2), "\n");
959
+ return [4 /*yield*/, fs.promises.writeFile(filePath, content)];
960
+ case 3:
961
+ _a.sent();
962
+ return [2 /*return*/, path.relative(process.cwd(), filePath)];
963
+ }
964
+ });
965
+ });
966
+ }
967
+ function promoteProjectSets(projectConfig, datasource, options) {
968
+ return __awaiter(this, void 0, void 0, function () {
969
+ var startTime, conflictPolicy, auditFormat, sets, sourceDatasource, destinationDatasource, plans, conflicts, preview, suffix, created, updated, unchanged, result, _a;
970
+ return __generator(this, function (_b) {
971
+ switch (_b.label) {
972
+ case 0:
973
+ startTime = Date.now();
974
+ conflictPolicy = normalizeConflictPolicy(options.conflicts);
975
+ auditFormat = normalizeAuditFormat(options.audit);
976
+ if (!projectConfig.sets)
977
+ throw new error_1.MessagevisorCLIError("Promotion is only available when `sets: true` is configured.");
978
+ if (!options.from)
979
+ throw new error_1.MessagevisorCLIError("Pass --from=<set>.");
980
+ if (!options.to)
981
+ throw new error_1.MessagevisorCLIError("Pass --to=<set>.");
982
+ if (options.from === options.to)
983
+ throw new error_1.MessagevisorCLIError("--from and --to must be different sets.");
984
+ return [4 /*yield*/, datasource.listSets()];
985
+ case 1:
986
+ sets = _b.sent();
987
+ if (!sets.includes(options.from))
988
+ throw new error_1.MessagevisorCLIError("Unknown source set \"".concat(options.from, "\". Available sets: ").concat(sets.join(", ") || "none", "."));
989
+ if (!sets.includes(options.to))
990
+ throw new error_1.MessagevisorCLIError("Unknown destination set \"".concat(options.to, "\". Available sets: ").concat(sets.join(", ") || "none", "."));
991
+ assertAllowedPromotionFlow(projectConfig, options.from, options.to);
992
+ sourceDatasource = datasource.forSet(options.from);
993
+ destinationDatasource = datasource.forSet(options.to);
994
+ return [4 /*yield*/, assertSetLintsClean(options.from, sourceDatasource)];
995
+ case 2:
996
+ _b.sent();
997
+ return [4 /*yield*/, assertSetLintsClean(options.to, destinationDatasource)];
998
+ case 3:
999
+ _b.sent();
1000
+ return [4 /*yield*/, getPromotionPlan(sourceDatasource, destinationDatasource, {
1001
+ target: options.target || [],
1002
+ locale: options.locale || [],
1003
+ includeMessages: options.includeMessages || [],
1004
+ excludeMessages: options.excludeMessages || [],
1005
+ excludeOverrides: options.excludeOverrides === true,
1006
+ allowEmpty: options.allowEmpty === true,
1007
+ conflicts: conflictPolicy,
1008
+ })];
1009
+ case 4:
1010
+ plans = _b.sent();
1011
+ conflicts = plans.flatMap(function (plan) { return plan.conflicts; });
1012
+ if (conflictPolicy === "fail" && conflicts.length > 0) {
1013
+ preview = conflicts
1014
+ .slice(0, 5)
1015
+ .map(function (conflict) { return "".concat(conflict.type, " \"").concat(conflict.key, "\" at ").concat(conflict.path); })
1016
+ .join("\n");
1017
+ suffix = conflicts.length > 5 ? "\n...and ".concat(conflicts.length - 5, " more") : "";
1018
+ throw new error_1.MessagevisorCLIError("Promotion has ".concat(conflicts.length, " conflict(s) and --conflicts=fail was used.\n").concat(preview).concat(suffix));
1019
+ }
1020
+ if (!(options.apply === true)) return [3 /*break*/, 6];
1021
+ return [4 /*yield*/, writePlan(destinationDatasource, plans)];
1022
+ case 5:
1023
+ _b.sent();
1024
+ _b.label = 6;
1025
+ case 6:
1026
+ created = plans
1027
+ .filter(function (plan) { return !plan.destination; })
1028
+ .map(function (plan) {
1029
+ return path.relative(process.cwd(), getEntityFilePath(destinationDatasource.getConfig(), plan.type, plan.key));
1030
+ });
1031
+ updated = plans
1032
+ .filter(function (plan) { return plan.destination && !deepEqual(plan.destination, plan.merged); })
1033
+ .map(function (plan) {
1034
+ return path.relative(process.cwd(), getEntityFilePath(destinationDatasource.getConfig(), plan.type, plan.key));
1035
+ });
1036
+ unchanged = plans
1037
+ .filter(function (plan) { return plan.destination && deepEqual(plan.destination, plan.merged); })
1038
+ .map(function (plan) {
1039
+ return path.relative(process.cwd(), getEntityFilePath(destinationDatasource.getConfig(), plan.type, plan.key));
1040
+ });
1041
+ result = {
1042
+ from: options.from,
1043
+ to: options.to,
1044
+ apply: options.apply === true,
1045
+ duration: Date.now() - startTime,
1046
+ filters: {
1047
+ targets: toArray(options.target),
1048
+ locales: toArray(options.locale),
1049
+ includeMessages: toArray(options.includeMessages),
1050
+ excludeMessages: toArray(options.excludeMessages),
1051
+ excludeOverrides: options.excludeOverrides === true,
1052
+ conflicts: conflictPolicy,
1053
+ },
1054
+ dependencies: {
1055
+ locales: plans.filter(function (plan) { return plan.type === "locale"; }).length,
1056
+ attributes: plans.filter(function (plan) { return plan.type === "attribute"; }).length,
1057
+ segments: plans.filter(function (plan) { return plan.type === "segment"; }).length,
1058
+ targets: plans.filter(function (plan) { return plan.type === "target"; }).length,
1059
+ messages: plans.filter(function (plan) { return plan.type === "message"; }).length,
1060
+ tests: plans.filter(function (plan) { return plan.type === "test"; }).length,
1061
+ },
1062
+ files: { created: created, updated: updated, unchanged: unchanged },
1063
+ conflicts: conflicts,
1064
+ };
1065
+ if (!(result.apply && auditFormat)) return [3 /*break*/, 8];
1066
+ _a = result;
1067
+ return [4 /*yield*/, writePromotionAudit(projectConfig, result, auditFormat)];
1068
+ case 7:
1069
+ _a.auditFilePath = _b.sent();
1070
+ _b.label = 8;
1071
+ case 8: return [2 /*return*/, result];
1072
+ }
1073
+ });
1074
+ });
1075
+ }
1076
+ function printPromoteResult(result, options) {
1077
+ if (options === void 0) { options = {}; }
1078
+ console.log("");
1079
+ console.log(cliFormat_1.CLI_FORMAT_BOLD, "Promoting Messagevisor set translations");
1080
+ console.log(" From: ".concat(result.from));
1081
+ console.log(" To: ".concat(result.to));
1082
+ console.log(" Mode: ".concat(result.apply ? "apply" : "preview"));
1083
+ if (result.filters.targets.length > 0)
1084
+ console.log(" Targets: ".concat(result.filters.targets.join(", ")));
1085
+ if (result.filters.locales.length > 0)
1086
+ console.log(" Locales: ".concat(result.filters.locales.join(", ")));
1087
+ if (result.filters.includeMessages.length > 0)
1088
+ console.log(" Include messages: ".concat(result.filters.includeMessages.join(", ")));
1089
+ if (result.filters.excludeMessages.length > 0)
1090
+ console.log(" Exclude messages: ".concat(result.filters.excludeMessages.join(", ")));
1091
+ console.log(" Conflict policy: ".concat(result.filters.conflicts));
1092
+ console.log(" Overrides: ".concat(result.filters.excludeOverrides ? "excluded; existing destination overrides are preserved" : "included"));
1093
+ console.log("");
1094
+ console.log(" Dependencies: ".concat(result.dependencies.locales, " locales, ").concat(result.dependencies.attributes, " attributes, ").concat(result.dependencies.segments, " segments, ").concat(result.dependencies.targets, " targets, ").concat(result.dependencies.messages, " messages, ").concat(result.dependencies.tests, " tests"));
1095
+ console.log(" Created: ".concat(result.files.created.length));
1096
+ console.log(" Updated: ".concat(result.files.updated.length));
1097
+ console.log(" Unchanged: ".concat(result.files.unchanged.length));
1098
+ console.log(" Conflicts: ".concat(result.conflicts.length));
1099
+ console.log("");
1100
+ printFileGroup("Created", result.files.created, 32);
1101
+ printFileGroup("Updated", result.files.updated, 33);
1102
+ if (options.showUnchanged === true) {
1103
+ printFileGroup("Unchanged", result.files.unchanged, 2);
1104
+ }
1105
+ printConflictPreview(result.conflicts);
1106
+ if (result.auditFilePath) {
1107
+ console.log(" Audit: ".concat((0, cliFormat_1.colorize)(result.auditFilePath, 36)));
1108
+ console.log("");
1109
+ }
1110
+ console.log(cliFormat_1.CLI_FORMAT_GREEN, result.apply ? "Promotion applied" : "Promotion preview complete");
1111
+ console.log(cliFormat_1.CLI_FORMAT_BOLD, "Time: ".concat((0, prettyDuration_1.prettyDuration)(result.duration)));
1112
+ }
1113
+ function printFileGroup(label, files, color) {
1114
+ if (files.length === 0) {
1115
+ return;
1116
+ }
1117
+ console.log(cliFormat_1.CLI_FORMAT_BOLD, label);
1118
+ for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
1119
+ var filePath = files_1[_i];
1120
+ console.log(" ".concat((0, cliFormat_1.colorize)(filePath, color)));
1121
+ }
1122
+ console.log("");
1123
+ }
1124
+ function printConflictPreview(conflicts) {
1125
+ if (conflicts.length === 0) {
1126
+ return;
1127
+ }
1128
+ console.log(cliFormat_1.CLI_FORMAT_BOLD, "Conflicts");
1129
+ for (var _i = 0, _a = conflicts.slice(0, 10); _i < _a.length; _i++) {
1130
+ var conflict = _a[_i];
1131
+ console.log(" ".concat((0, cliFormat_1.colorize)(conflict.type, 33), " ").concat(conflict.key, " ").concat((0, cliFormat_1.colorize)(conflict.path, 2)));
1132
+ }
1133
+ if (conflicts.length > 10) {
1134
+ console.log(" ".concat((0, cliFormat_1.colorize)("...and ".concat(conflicts.length - 10, " more"), 2)));
1135
+ }
1136
+ console.log("");
1137
+ }
1138
+ exports.promotePlugin = {
1139
+ command: "promote",
1140
+ handler: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
1141
+ var result, error_2;
1142
+ var projectConfig = _b.projectConfig, datasource = _b.datasource, parsed = _b.parsed;
1143
+ return __generator(this, function (_c) {
1144
+ switch (_c.label) {
1145
+ case 0:
1146
+ _c.trys.push([0, 2, , 3]);
1147
+ return [4 /*yield*/, promoteProjectSets(projectConfig, datasource, {
1148
+ from: parsed.from,
1149
+ to: parsed.to,
1150
+ target: parsed.target,
1151
+ locale: parsed.locale,
1152
+ includeMessages: parsed.includeMessages,
1153
+ excludeMessages: parsed.excludeMessages,
1154
+ excludeOverrides: parsed.excludeOverrides,
1155
+ conflicts: parsed.conflicts,
1156
+ allowEmpty: parsed.allowEmpty,
1157
+ apply: parsed.apply === true || parsed.apply === "true",
1158
+ audit: parsed.audit,
1159
+ })];
1160
+ case 1:
1161
+ result = _c.sent();
1162
+ return [3 /*break*/, 3];
1163
+ case 2:
1164
+ error_2 = _c.sent();
1165
+ if ((0, error_1.printMessagevisorCLIError)(error_2)) {
1166
+ return [2 /*return*/, false];
1167
+ }
1168
+ throw error_2;
1169
+ case 3:
1170
+ printPromoteResult(result, {
1171
+ showUnchanged: parsed.showUnchanged === true || parsed.showUnchanged === "true",
1172
+ });
1173
+ return [2 /*return*/];
1174
+ }
1175
+ });
1176
+ }); },
1177
+ examples: [
1178
+ {
1179
+ command: "promote --from=dev --to=staging",
1180
+ description: "preview all translations that can be promoted from one set to another",
1181
+ },
1182
+ {
1183
+ command: "promote --from=dev --to=staging --target=web",
1184
+ description: "preview translations affecting a target",
1185
+ },
1186
+ {
1187
+ command: "promote --from=dev --to=staging --excludeOverrides",
1188
+ description: "preview messages without copying overrides",
1189
+ },
1190
+ {
1191
+ command: "promote --from=dev --to=staging --conflicts=fail",
1192
+ description: "fail instead of overwriting conflicting destination fields",
1193
+ },
1194
+ {
1195
+ command: "promote --from=dev --to=staging --apply",
1196
+ description: "apply a promotion and write destination files",
1197
+ },
1198
+ {
1199
+ command: "promote --from=dev --to=staging --apply --audit=markdown",
1200
+ description: "write a promotion audit file",
1201
+ },
1202
+ {
1203
+ command: "promote --from=dev --to=staging --showUnchanged",
1204
+ description: "preview a promotion and include unchanged entries",
1205
+ },
1206
+ ],
1207
+ };
1208
+ //# sourceMappingURL=index.js.map