@memberjunction/metadata-sync 6.2.0-edge.4 → 6.2.0-edge.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +115 -51
  2. package/dist/config.d.ts +5 -0
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js.map +1 -1
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/RecordProcessor.d.ts +98 -0
  10. package/dist/lib/RecordProcessor.d.ts.map +1 -1
  11. package/dist/lib/RecordProcessor.js +424 -22
  12. package/dist/lib/RecordProcessor.js.map +1 -1
  13. package/dist/lib/RelatedEntityHandler.d.ts +4 -1
  14. package/dist/lib/RelatedEntityHandler.d.ts.map +1 -1
  15. package/dist/lib/RelatedEntityHandler.js +49 -11
  16. package/dist/lib/RelatedEntityHandler.js.map +1 -1
  17. package/dist/lib/created-record-key.d.ts +34 -0
  18. package/dist/lib/created-record-key.d.ts.map +1 -0
  19. package/dist/lib/created-record-key.js +46 -0
  20. package/dist/lib/created-record-key.js.map +1 -0
  21. package/dist/lib/deletion-auditor.d.ts.map +1 -1
  22. package/dist/lib/deletion-auditor.js +33 -2
  23. package/dist/lib/deletion-auditor.js.map +1 -1
  24. package/dist/lib/entity-field-names.d.ts +11 -0
  25. package/dist/lib/entity-field-names.d.ts.map +1 -0
  26. package/dist/lib/entity-field-names.js +15 -0
  27. package/dist/lib/entity-field-names.js.map +1 -0
  28. package/dist/lib/env-derived-fields.d.ts +23 -0
  29. package/dist/lib/env-derived-fields.d.ts.map +1 -0
  30. package/dist/lib/env-derived-fields.js +53 -0
  31. package/dist/lib/env-derived-fields.js.map +1 -0
  32. package/dist/lib/env-display.d.ts +54 -0
  33. package/dist/lib/env-display.d.ts.map +1 -0
  34. package/dist/lib/env-display.js +156 -0
  35. package/dist/lib/env-display.js.map +1 -0
  36. package/dist/lib/env-reference.d.ts +104 -0
  37. package/dist/lib/env-reference.d.ts.map +1 -0
  38. package/dist/lib/env-reference.js +241 -0
  39. package/dist/lib/env-reference.js.map +1 -0
  40. package/dist/lib/env-sql-redactor.d.ts +74 -0
  41. package/dist/lib/env-sql-redactor.d.ts.map +1 -0
  42. package/dist/lib/env-sql-redactor.js +297 -0
  43. package/dist/lib/env-sql-redactor.js.map +1 -0
  44. package/dist/lib/existing-record-index.d.ts +70 -0
  45. package/dist/lib/existing-record-index.d.ts.map +1 -0
  46. package/dist/lib/existing-record-index.js +158 -0
  47. package/dist/lib/existing-record-index.js.map +1 -0
  48. package/dist/lib/ignore-directories.d.ts +10 -0
  49. package/dist/lib/ignore-directories.d.ts.map +1 -0
  50. package/dist/lib/ignore-directories.js +12 -0
  51. package/dist/lib/ignore-directories.js.map +1 -0
  52. package/dist/lib/json-record-lines.d.ts +17 -0
  53. package/dist/lib/json-record-lines.d.ts.map +1 -0
  54. package/dist/lib/json-record-lines.js +170 -0
  55. package/dist/lib/json-record-lines.js.map +1 -0
  56. package/dist/lib/json-subproperty-externalization.d.ts.map +1 -1
  57. package/dist/lib/json-subproperty-externalization.js +3 -1
  58. package/dist/lib/json-subproperty-externalization.js.map +1 -1
  59. package/dist/lib/lookup-reference.d.ts +38 -0
  60. package/dist/lib/lookup-reference.d.ts.map +1 -0
  61. package/dist/lib/lookup-reference.js +62 -0
  62. package/dist/lib/lookup-reference.js.map +1 -0
  63. package/dist/lib/provider-utils.d.ts.map +1 -1
  64. package/dist/lib/provider-utils.js +2 -4
  65. package/dist/lib/provider-utils.js.map +1 -1
  66. package/dist/lib/pull-option-overrides.d.ts +24 -0
  67. package/dist/lib/pull-option-overrides.d.ts.map +1 -0
  68. package/dist/lib/pull-option-overrides.js +39 -0
  69. package/dist/lib/pull-option-overrides.js.map +1 -0
  70. package/dist/lib/push-directories.d.ts +42 -0
  71. package/dist/lib/push-directories.d.ts.map +1 -0
  72. package/dist/lib/push-directories.js +71 -0
  73. package/dist/lib/push-directories.js.map +1 -0
  74. package/dist/lib/push-when.d.ts +38 -0
  75. package/dist/lib/push-when.d.ts.map +1 -0
  76. package/dist/lib/push-when.js +84 -0
  77. package/dist/lib/push-when.js.map +1 -0
  78. package/dist/lib/record-dependency-analyzer.d.ts +2 -0
  79. package/dist/lib/record-dependency-analyzer.d.ts.map +1 -1
  80. package/dist/lib/record-dependency-analyzer.js.map +1 -1
  81. package/dist/lib/record-file-glob.d.ts +11 -0
  82. package/dist/lib/record-file-glob.d.ts.map +1 -0
  83. package/dist/lib/record-file-glob.js +10 -0
  84. package/dist/lib/record-file-glob.js.map +1 -0
  85. package/dist/lib/reference-parser.d.ts +3 -2
  86. package/dist/lib/reference-parser.d.ts.map +1 -1
  87. package/dist/lib/reference-parser.js +27 -27
  88. package/dist/lib/reference-parser.js.map +1 -1
  89. package/dist/lib/sync-engine.d.ts +46 -4
  90. package/dist/lib/sync-engine.d.ts.map +1 -1
  91. package/dist/lib/sync-engine.js +215 -59
  92. package/dist/lib/sync-engine.js.map +1 -1
  93. package/dist/lib/sync-state-manager.d.ts +7 -3
  94. package/dist/lib/sync-state-manager.d.ts.map +1 -1
  95. package/dist/lib/sync-state-manager.js +19 -4
  96. package/dist/lib/sync-state-manager.js.map +1 -1
  97. package/dist/lib/watch-file-filter.d.ts +31 -0
  98. package/dist/lib/watch-file-filter.d.ts.map +1 -0
  99. package/dist/lib/watch-file-filter.js +64 -0
  100. package/dist/lib/watch-file-filter.js.map +1 -0
  101. package/dist/plugins/index.d.ts.map +1 -1
  102. package/dist/plugins/index.js +44 -14
  103. package/dist/plugins/index.js.map +1 -1
  104. package/dist/services/PullService.d.ts +41 -1
  105. package/dist/services/PullService.d.ts.map +1 -1
  106. package/dist/services/PullService.js +261 -101
  107. package/dist/services/PullService.js.map +1 -1
  108. package/dist/services/PushService.d.ts +59 -0
  109. package/dist/services/PushService.d.ts.map +1 -1
  110. package/dist/services/PushService.js +435 -173
  111. package/dist/services/PushService.js.map +1 -1
  112. package/dist/services/ValidationService.d.ts +43 -8
  113. package/dist/services/ValidationService.d.ts.map +1 -1
  114. package/dist/services/ValidationService.js +338 -127
  115. package/dist/services/ValidationService.js.map +1 -1
  116. package/dist/services/WatchService.d.ts +26 -0
  117. package/dist/services/WatchService.d.ts.map +1 -1
  118. package/dist/services/WatchService.js +210 -75
  119. package/dist/services/WatchService.js.map +1 -1
  120. package/dist/types/validation.d.ts +6 -0
  121. package/dist/types/validation.d.ts.map +1 -1
  122. package/package.json +17 -16
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileoverview Finds the values of the `@env:` references in an existing record file, so pull can
3
+ * leave out a read-only field whose database value holds one of them (for example a key path that
4
+ * the database builds from an env-sourced primary key).
5
+ * @module env-derived-fields
6
+ */
7
+ import type { EntityInfo } from '@memberjunction/core';
8
+ import type { RecordData } from './sync-engine.js';
9
+ /** The value of one `@env:` reference in a record file. Never print `Value`. */
10
+ export interface EnvSourcedValue {
11
+ VariableName: string;
12
+ Value: string;
13
+ /** True for a UUID value, which is compared without case. */
14
+ IgnoreCase: boolean;
15
+ }
16
+ /**
17
+ * The values of the set variables that the record file uses in `primaryKey` and anywhere in
18
+ * `fields`. A non-UUID value shorter than 6 characters is left out, as in masking.
19
+ */
20
+ export declare function EnvSourcedValuesOf(existing: RecordData | undefined, entityInfo: EntityInfo | null | undefined, env?: NodeJS.ProcessEnv): EnvSourcedValue[];
21
+ /** The first env-sourced value that the database value holds, or undefined. */
22
+ export declare function FindEnvSourcedValue(databaseValue: unknown, values: ReadonlyArray<EnvSourcedValue>): EnvSourcedValue | undefined;
23
+ //# sourceMappingURL=env-derived-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-derived-fields.d.ts","sourceRoot":"","sources":["../../src/lib/env-derived-fields.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAOhD,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EACzC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,eAAe,EAAE,CAanB;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,eAAe,GAAG,SAAS,CAO/H"}
@@ -0,0 +1,53 @@
1
+ import { MIN_MASKED_VALUE_LENGTH } from './env-display.js';
2
+ import { ParseEnvReference } from './env-reference.js';
3
+ /** A UUID text, in any case. */
4
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
5
+ /**
6
+ * The values of the set variables that the record file uses in `primaryKey` and anywhere in
7
+ * `fields`. A non-UUID value shorter than 6 characters is left out, as in masking.
8
+ */
9
+ export function EnvSourcedValuesOf(existing, entityInfo, env = process.env) {
10
+ if (!existing) {
11
+ return [];
12
+ }
13
+ const values = [];
14
+ for (const [keyName, keyValue] of Object.entries(existing.primaryKey ?? {})) {
15
+ const isUuid = entityInfo?.Fields.find((f) => f.Name.toLowerCase() === keyName.toLowerCase())?.IsUniqueIdentifier === true;
16
+ addValue(values, keyValue, isUuid, env);
17
+ }
18
+ for (const reference of envReferencesIn(existing.fields)) {
19
+ addValue(values, reference, false, env);
20
+ }
21
+ return values;
22
+ }
23
+ /** The first env-sourced value that the database value holds, or undefined. */
24
+ export function FindEnvSourcedValue(databaseValue, values) {
25
+ if (values.length === 0 || databaseValue === null || databaseValue === undefined) {
26
+ return undefined;
27
+ }
28
+ const text = typeof databaseValue === 'string' ? databaseValue : JSON.stringify(databaseValue);
29
+ const lowerText = text.toLowerCase();
30
+ return values.find((value) => (value.IgnoreCase ? lowerText.includes(value.Value.toLowerCase()) : text.includes(value.Value)));
31
+ }
32
+ function addValue(values, reference, isUuid, env) {
33
+ const parsed = ParseEnvReference(reference);
34
+ const value = parsed ? env[parsed.VariableName]?.trim() : undefined;
35
+ if (!parsed || !value || (!isUuid && value.length < MIN_MASKED_VALUE_LENGTH)) {
36
+ return;
37
+ }
38
+ values.push({ VariableName: parsed.VariableName, Value: value, IgnoreCase: isUuid || UUID_PATTERN.test(value) });
39
+ }
40
+ /** Every string in the value, at any depth, that is an `@env:` reference. */
41
+ function envReferencesIn(value) {
42
+ if (typeof value === 'string') {
43
+ return ParseEnvReference(value) ? [value] : [];
44
+ }
45
+ if (Array.isArray(value)) {
46
+ return value.flatMap(envReferencesIn);
47
+ }
48
+ if (value !== null && typeof value === 'object') {
49
+ return Object.values(value).flatMap(envReferencesIn);
50
+ }
51
+ return [];
52
+ }
53
+ //# sourceMappingURL=env-derived-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-derived-fields.js","sourceRoot":"","sources":["../../src/lib/env-derived-fields.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @fileoverview Display text for values that come from `@env:`. Push prints these in place of
3
+ * the values in diffs, change reports, save-failure dumps and error text.
4
+ * @module env-display
5
+ */
6
+ /** Shown for the old database value of an env-sourced field. */
7
+ export declare const ENV_HIDDEN_VALUE = "<hidden>";
8
+ /**
9
+ * Values shorter than this are not searched for in free text, so short values do not match unrelated text.
10
+ * Display masking, the pull left-over check and the copied-value check all use it.
11
+ */
12
+ export declare const MIN_MASKED_VALUE_LENGTH = 6;
13
+ /** `<from @env:A>`, or `<from @env:A, @env:B>` for a field that uses more than one variable. */
14
+ export declare function EnvSourceLabel(variableNames: Iterable<string>): string;
15
+ /**
16
+ * The thrown value as an Error whose message and stack hold no variable value. A value that is not
17
+ * an Error is wrapped in a new Error with the masked text. Only `message` and `stack` are masked;
18
+ * `cause` and other properties are left as they are.
19
+ */
20
+ export declare function MaskedError(thrown: unknown, mask: EnvDisplayMask): Error;
21
+ /** Masks the env-sourced fields of one record in printed text. */
22
+ export declare class EnvDisplayMask {
23
+ private readonly fields;
24
+ private readonly env;
25
+ /** Variables searched for by MaskText that belong to no field. */
26
+ private textVariables;
27
+ constructor(fields?: ReadonlyMap<string, ReadonlySet<string>>, env?: NodeJS.ProcessEnv);
28
+ /** A mask for free text only: MaskText searches for these variables, and no field is env-sourced. */
29
+ static ForVariables(variableNames: Iterable<string>, env?: NodeJS.ProcessEnv): EnvDisplayMask;
30
+ /** True when the record has no env-sourced field. */
31
+ get IsEmpty(): boolean;
32
+ /** True when the field is env-sourced. The name matches exactly, or else without regard to case. */
33
+ IsEnvField(fieldName: string): boolean;
34
+ /** The old value to print: `<hidden>` for an env-sourced field, else the formatted value. */
35
+ OldValue(fieldName: string, formatted: string): string;
36
+ /** The new value to print: `<from @env:VAR>` for an env-sourced field, else the formatted value. */
37
+ NewValue(fieldName: string, formatted: string): string;
38
+ /**
39
+ * Replaces each value of this record's variables in free text with its label, without regard to case.
40
+ * A variable is searched for only when its trimmed value is at least `MIN_MASKED_VALUE_LENGTH` long.
41
+ * Matches the value as is, trimmed, with doubled single quotes, JSON-escaped once, and JSON-escaped
42
+ * with doubled single quotes. Every match is found in the original text; matches that overlap become
43
+ * one label that names all their variables, so no part of any value is left.
44
+ */
45
+ MaskText(text: string): string;
46
+ /** Every match of every form in the text, overlapping matches included. */
47
+ private findMatches;
48
+ /** The variables of a field, found by exact name, or else by name without regard to case. */
49
+ private variablesFor;
50
+ /** Every searched form of every set variable. */
51
+ private maskForms;
52
+ private variableNames;
53
+ }
54
+ //# sourceMappingURL=env-display.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-display.d.ts","sourceRoot":"","sources":["../../src/lib/env-display.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,gGAAgG;AAChG,wBAAgB,cAAc,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAGtE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,KAAK,CAUxE;AAED,kEAAkE;AAClE,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;IAClE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,kEAAkE;IAClE,OAAO,CAAC,aAAa,CAAkC;gBAE3C,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB;IAKnG,qGAAqG;IACrG,MAAM,CAAC,YAAY,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,cAAc;IAM1G,qDAAqD;IACrD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,oGAAoG;IACpG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAItC,6FAA6F;IAC7F,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAItD,oGAAoG;IACpG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAKtD;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAW9B,2EAA2E;IAC3E,OAAO,CAAC,WAAW;IAYnB,6FAA6F;IAC7F,OAAO,CAAC,YAAY;IAcpB,iDAAiD;IACjD,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,aAAa;CAOtB"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @fileoverview Display text for values that come from `@env:`. Push prints these in place of
3
+ * the values in diffs, change reports, save-failure dumps and error text.
4
+ * @module env-display
5
+ */
6
+ /** Shown for the old database value of an env-sourced field. */
7
+ export const ENV_HIDDEN_VALUE = '<hidden>';
8
+ /**
9
+ * Values shorter than this are not searched for in free text, so short values do not match unrelated text.
10
+ * Display masking, the pull left-over check and the copied-value check all use it.
11
+ */
12
+ export const MIN_MASKED_VALUE_LENGTH = 6;
13
+ /** `<from @env:A>`, or `<from @env:A, @env:B>` for a field that uses more than one variable. */
14
+ export function EnvSourceLabel(variableNames) {
15
+ const names = [...new Set(variableNames)].sort();
16
+ return `<from ${names.map((name) => `@env:${name}`).join(', ')}>`;
17
+ }
18
+ /**
19
+ * The thrown value as an Error whose message and stack hold no variable value. A value that is not
20
+ * an Error is wrapped in a new Error with the masked text. Only `message` and `stack` are masked;
21
+ * `cause` and other properties are left as they are.
22
+ */
23
+ export function MaskedError(thrown, mask) {
24
+ if (!(thrown instanceof Error)) {
25
+ const text = typeof thrown === 'object' && thrown !== null ? JSON.stringify(thrown) : String(thrown);
26
+ return new Error(mask.MaskText(text));
27
+ }
28
+ thrown.message = mask.MaskText(thrown.message);
29
+ if (thrown.stack) {
30
+ thrown.stack = mask.MaskText(thrown.stack);
31
+ }
32
+ return thrown;
33
+ }
34
+ /** Masks the env-sourced fields of one record in printed text. */
35
+ export class EnvDisplayMask {
36
+ constructor(fields, env = process.env) {
37
+ /** Variables searched for by MaskText that belong to no field. */
38
+ this.textVariables = new Set();
39
+ this.fields = fields ?? new Map();
40
+ this.env = env;
41
+ }
42
+ /** A mask for free text only: MaskText searches for these variables, and no field is env-sourced. */
43
+ static ForVariables(variableNames, env = process.env) {
44
+ const mask = new EnvDisplayMask(undefined, env);
45
+ mask.textVariables = new Set(variableNames);
46
+ return mask;
47
+ }
48
+ /** True when the record has no env-sourced field. */
49
+ get IsEmpty() {
50
+ return this.fields.size === 0;
51
+ }
52
+ /** True when the field is env-sourced. The name matches exactly, or else without regard to case. */
53
+ IsEnvField(fieldName) {
54
+ return this.variablesFor(fieldName) !== undefined;
55
+ }
56
+ /** The old value to print: `<hidden>` for an env-sourced field, else the formatted value. */
57
+ OldValue(fieldName, formatted) {
58
+ return this.IsEnvField(fieldName) ? ENV_HIDDEN_VALUE : formatted;
59
+ }
60
+ /** The new value to print: `<from @env:VAR>` for an env-sourced field, else the formatted value. */
61
+ NewValue(fieldName, formatted) {
62
+ const variables = this.variablesFor(fieldName);
63
+ return variables ? EnvSourceLabel(variables) : formatted;
64
+ }
65
+ /**
66
+ * Replaces each value of this record's variables in free text with its label, without regard to case.
67
+ * A variable is searched for only when its trimmed value is at least `MIN_MASKED_VALUE_LENGTH` long.
68
+ * Matches the value as is, trimmed, with doubled single quotes, JSON-escaped once, and JSON-escaped
69
+ * with doubled single quotes. Every match is found in the original text; matches that overlap become
70
+ * one label that names all their variables, so no part of any value is left.
71
+ */
72
+ MaskText(text) {
73
+ const ranges = mergeRanges(this.findMatches(text));
74
+ let result = '';
75
+ let position = 0;
76
+ for (const range of ranges) {
77
+ result += text.slice(position, range.Start) + EnvSourceLabel(range.Names);
78
+ position = range.End;
79
+ }
80
+ return result + text.slice(position);
81
+ }
82
+ /** Every match of every form in the text, overlapping matches included. */
83
+ findMatches(text) {
84
+ const matches = [];
85
+ for (const { Form, Name } of this.maskForms()) {
86
+ const pattern = new RegExp(escapeRegExp(Form), 'gi');
87
+ for (let match = pattern.exec(text); match !== null; match = pattern.exec(text)) {
88
+ matches.push({ Start: match.index, End: match.index + Form.length, Names: [Name] });
89
+ pattern.lastIndex = match.index + 1;
90
+ }
91
+ }
92
+ return matches;
93
+ }
94
+ /** The variables of a field, found by exact name, or else by name without regard to case. */
95
+ variablesFor(fieldName) {
96
+ const exact = this.fields.get(fieldName);
97
+ if (exact) {
98
+ return exact;
99
+ }
100
+ const lowerName = fieldName.toLowerCase();
101
+ for (const [name, variables] of this.fields) {
102
+ if (name.toLowerCase() === lowerName) {
103
+ return variables;
104
+ }
105
+ }
106
+ return undefined;
107
+ }
108
+ /** Every searched form of every set variable. */
109
+ maskForms() {
110
+ const forms = [];
111
+ for (const name of this.variableNames()) {
112
+ const value = this.env[name];
113
+ if (value === undefined || value.trim().length < MIN_MASKED_VALUE_LENGTH) {
114
+ continue;
115
+ }
116
+ const jsonForm = JSON.stringify(value).slice(1, -1);
117
+ const variants = new Set([value, value.trim(), value.replace(/'/g, "''"), jsonForm, jsonForm.replace(/'/g, "''")]);
118
+ variants.forEach((form) => forms.push({ Form: form, Name: name }));
119
+ }
120
+ return forms;
121
+ }
122
+ variableNames() {
123
+ const variables = new Set(this.textVariables);
124
+ for (const names of this.fields.values()) {
125
+ names.forEach((name) => variables.add(name));
126
+ }
127
+ return variables;
128
+ }
129
+ }
130
+ /**
131
+ * Sorts the ranges and joins the ones that overlap. A range inside another adds no name, so a value
132
+ * that is part of a longer value is labeled by the longer one.
133
+ */
134
+ function mergeRanges(ranges) {
135
+ const sorted = [...ranges].sort((a, b) => a.Start - b.Start || b.End - a.End);
136
+ const merged = [];
137
+ for (const range of sorted) {
138
+ const last = merged[merged.length - 1];
139
+ if (last && range.End <= last.End) {
140
+ continue;
141
+ }
142
+ if (last && range.Start < last.End) {
143
+ last.End = range.End;
144
+ last.Names.push(...range.Names);
145
+ }
146
+ else {
147
+ merged.push({ Start: range.Start, End: range.End, Names: [...range.Names] });
148
+ }
149
+ }
150
+ return merged;
151
+ }
152
+ /** Escapes the characters that have a meaning in a regular expression. */
153
+ function escapeRegExp(text) {
154
+ return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
155
+ }
156
+ //# sourceMappingURL=env-display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-display.js","sourceRoot":"","sources":["../../src/lib/env-display.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * @fileoverview Parsing and checks for `@env:` references in metadata files.
3
+ * @module env-reference
4
+ */
5
+ /** Matches `@env:VARIABLE`, with an optional `?optional` modifier. */
6
+ export declare const ENV_REFERENCE_PATTERN: RegExp;
7
+ /** A parsed `@env:` reference. */
8
+ export interface EnvReference {
9
+ /** Name of the environment variable. */
10
+ VariableName: string;
11
+ /** True when the reference ends with `?optional`. */
12
+ Optional: boolean;
13
+ }
14
+ /**
15
+ * Parses an `@env:` reference.
16
+ * @returns The parsed reference, or null when the value is not a valid `@env:` reference
17
+ */
18
+ export declare function ParseEnvReference(value: unknown): EnvReference | null;
19
+ /** True when an environment value is `true` or `1`, ignoring case and surrounding spaces. */
20
+ export declare function IsEnvFlagTrue(value: string | undefined): boolean;
21
+ /** Thrown when an `@env:VAR?optional` reference names a variable that is not set. */
22
+ export declare class OptionalEnvMissingError extends Error {
23
+ readonly VariableName: string;
24
+ constructor(variableName: string);
25
+ }
26
+ /** Thrown when a non-optional `@env:` reference names a variable that is not set. Holds names only. */
27
+ export declare class EnvVariableNotSetError extends Error {
28
+ readonly VariableName: string;
29
+ /**
30
+ * The field that uses the reference, such as `fields.Description`, `primaryKey.ID` or
31
+ * `collections.Lines[0].fields.Name` for a composition child, when known.
32
+ */
33
+ readonly Field: string | undefined;
34
+ /** The entity of the record that holds the field, when it is not the record push reports. */
35
+ readonly EntityName: string | undefined;
36
+ constructor(variableName: string, field?: string, entityName?: string);
37
+ /** The same error for the given field (and entity, when given). */
38
+ ForField(field: string, entityName?: string): EnvVariableNotSetError;
39
+ /** The same error inside a composition path, such as `collections.Lines[0]`; an entity already named is kept. */
40
+ Within(compositionPath: string, entityName: string | undefined): EnvVariableNotSetError;
41
+ }
42
+ /** The warning push gives when it leaves out a field whose optional variable is not set. */
43
+ export declare function OptionalEnvSkipMessage(entityName: string, fieldName: string, variableName: string): string;
44
+ /** How a kept `@env:` reference compares with the database value. */
45
+ export type EnvReferenceCheck = 'Match' | 'Drift' | 'Unset';
46
+ /** An `@env:` reference that pull writes back in place of the database value. */
47
+ export interface KeptEnvReference {
48
+ /** The reference exactly as the existing file has it. */
49
+ Reference: string;
50
+ VariableName: string;
51
+ Check: EnvReferenceCheck;
52
+ }
53
+ /**
54
+ * Decides whether pull keeps an existing `@env:` reference instead of the database value.
55
+ * The result never contains the variable's value.
56
+ * @returns The reference to keep, or null when the existing value is not a valid `@env:` reference
57
+ */
58
+ export declare function KeepEnvReference(existingValue: unknown, databaseValue: unknown, env?: NodeJS.ProcessEnv): KeptEnvReference | null;
59
+ /** A JSON value. */
60
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
61
+ [key: string]: JsonValue;
62
+ };
63
+ /** A JSON object or array. */
64
+ export type JsonContainer = JsonValue[] | {
65
+ [key: string]: JsonValue;
66
+ };
67
+ /** True for a plain object or an array. */
68
+ export declare function IsJsonContainer(value: unknown): value is JsonContainer;
69
+ /** True when an object or array holds a valid `@env:` string at any depth. */
70
+ export declare function HasNestedEnvReference(value: unknown): boolean;
71
+ /** One `@env:` reference inside a JSON field that pull keeps. Never holds a value. */
72
+ export interface KeptNestedEnvReference {
73
+ /** Path inside the field: `auth.apiKey`, `items[2].token`, `["x.y"]`. */
74
+ Path: string;
75
+ /** The reference exactly as the existing file has it. */
76
+ Reference: string;
77
+ VariableName: string;
78
+ Check: EnvReferenceCheck;
79
+ }
80
+ /** What pull writes for a JSON field that holds `@env:` references. */
81
+ export interface NestedEnvKeepResult {
82
+ /** The database JSON with each kept reference put back, or the file value when `KeptFileValue` is true. */
83
+ Value: JsonValue;
84
+ Kept: KeptNestedEnvReference[];
85
+ /**
86
+ * True when the file value is kept as is: the database value is not a JSON object or array, or the
87
+ * merged database JSON still held a referenced variable's trimmed value of 6 or more characters.
88
+ */
89
+ KeptFileValue: boolean;
90
+ /**
91
+ * Names of the variables whose value the merged database JSON still held, sorted. Not empty only
92
+ * when `KeptFileValue` is true for this reason.
93
+ */
94
+ LeftValueVariables: string[];
95
+ }
96
+ /**
97
+ * Keeps `@env:` references inside a JSON field. The database value decides the structure and every
98
+ * other leaf. A reference is put back only at a path that also exists in the database value; arrays
99
+ * match by index. When the merged JSON would still hold the value (6 or more characters) of a variable
100
+ * that the existing value references, the existing value is kept as is.
101
+ * @returns null when the existing value is not an object or array, or holds no valid `@env:` string
102
+ */
103
+ export declare function KeepNestedEnvReferences(existingValue: unknown, databaseValue: unknown, env?: NodeJS.ProcessEnv): NestedEnvKeepResult | null;
104
+ //# sourceMappingURL=env-reference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-reference.d.ts","sourceRoot":"","sources":["../../src/lib/env-reference.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,sEAAsE;AACtE,eAAO,MAAM,qBAAqB,QAAgC,CAAC;AAEnE,kCAAkC;AAClC,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CASrE;AAED,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGhE;AAED,qFAAqF;AACrF,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,SAAgB,YAAY,EAAE,MAAM,CAAC;gBAEzB,YAAY,EAAE,MAAM;CAKjC;AAED,uGAAuG;AACvG,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,SAAgB,YAAY,EAAE,MAAM,CAAC;IACrC;;;OAGG;IACH,SAAgB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,6FAA6F;IAC7F,SAAgB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;gBAEnC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;IAQrE,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,sBAAsB;IAIpE,iHAAiH;IACjH,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,sBAAsB;CAIxF;AAED,4FAA4F;AAC5F,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAE1G;AAED,qEAAqE;AACrE,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5D,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,OAAO,EACtB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,gBAAgB,GAAG,IAAI,CAczB;AAMD,oBAAoB;AACpB,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEtG,8BAA8B;AAC9B,MAAM,MAAM,aAAa,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEvE,2CAA2C;AAC3C,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAKtE;AAED,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE7D;AAeD,sFAAsF;AACtF,MAAM,WAAW,sBAAsB;IACrC,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,iBAAiB,CAAC;CAC1B;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IAClC,2GAA2G;IAC3G,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,sBAAsB,EAAE,CAAC;IAC/B;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,OAAO,EACtB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,mBAAmB,GAAG,IAAI,CAqB5B"}