@arkebcacy/beacon-cli-temp 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cs/labels/Label.d.ts +1 -1
- package/dist/cs/labels/Label.d.ts.map +1 -1
- package/dist/cs/labels/Label.js +1 -3
- package/dist/cs/labels/Label.js.map +1 -1
- package/dist/cs/labels/getAllLabels.js +1 -1
- package/dist/cs/labels/getAllLabels.js.map +1 -1
- package/dist/cs/locales/addLocale.d.ts +11 -0
- package/dist/cs/locales/addLocale.d.ts.map +1 -0
- package/dist/cs/locales/addLocale.js +36 -0
- package/dist/cs/locales/addLocale.js.map +1 -0
- package/dist/cs/locales/ensureLocaleExists.d.ts +11 -0
- package/dist/cs/locales/ensureLocaleExists.d.ts.map +1 -0
- package/dist/cs/locales/ensureLocaleExists.js +38 -0
- package/dist/cs/locales/ensureLocaleExists.js.map +1 -0
- package/dist/cs/locales/getLocales.d.ts +12 -0
- package/dist/cs/locales/getLocales.d.ts.map +1 -0
- package/dist/cs/locales/getLocales.js +23 -0
- package/dist/cs/locales/getLocales.js.map +1 -0
- package/dist/dto/labels/flatten.js +1 -1
- package/dist/dto/labels/flatten.js.map +1 -1
- package/dist/dto/labels/organize.d.ts.map +1 -1
- package/dist/dto/labels/organize.js +15 -14
- package/dist/dto/labels/organize.js.map +1 -1
- package/dist/schema/entries/toContentstack.d.ts.map +1 -1
- package/dist/schema/entries/toContentstack.js +30 -5
- package/dist/schema/entries/toContentstack.js.map +1 -1
- package/dist/schema/entries/toFilesystem.js +23 -10
- package/dist/schema/entries/toFilesystem.js.map +1 -1
- package/dist/schema/labels/lib/labelHelpers.d.ts +3 -0
- package/dist/schema/labels/lib/labelHelpers.d.ts.map +1 -0
- package/dist/schema/labels/lib/labelHelpers.js +34 -0
- package/dist/schema/labels/lib/labelHelpers.js.map +1 -0
- package/dist/schema/labels/lib/labelOperations.d.ts +6 -0
- package/dist/schema/labels/lib/labelOperations.d.ts.map +1 -0
- package/dist/schema/labels/lib/labelOperations.js +57 -0
- package/dist/schema/labels/lib/labelOperations.js.map +1 -0
- package/dist/schema/labels/toContentstack.d.ts.map +1 -1
- package/dist/schema/labels/toContentstack.js +142 -105
- package/dist/schema/labels/toContentstack.js.map +1 -1
- package/dist/schema/labels/toFilesystem.d.ts.map +1 -1
- package/dist/schema/labels/toFilesystem.js +6 -3
- package/dist/schema/labels/toFilesystem.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/cs/labels/Label.ts +2 -6
- package/src/cs/labels/getAllLabels.ts +1 -1
- package/src/cs/locales/addLocale.ts +59 -0
- package/src/cs/locales/ensureLocaleExists.ts +51 -0
- package/src/cs/locales/getLocales.ts +38 -0
- package/src/dto/labels/flatten.test.ts +16 -16
- package/src/dto/labels/flatten.ts +1 -1
- package/src/dto/labels/organize.test.ts +19 -19
- package/src/dto/labels/organize.ts +15 -14
- package/src/schema/entries/toContentstack.ts +75 -6
- package/src/schema/entries/toFilesystem.ts +29 -14
- package/src/schema/labels/lib/labelHelpers.ts +36 -0
- package/src/schema/labels/lib/labelOperations.ts +74 -0
- package/src/schema/labels/toContentstack.ts +204 -109
- package/src/schema/labels/toFilesystem.ts +10 -3
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import ContentstackError from '#cli/cs/api/ContentstackError.js';
|
|
2
|
+
import isRecord from '#cli/util/isRecord.js';
|
|
3
|
+
import type Ctx from '../../ctx/Ctx.js';
|
|
4
|
+
import type { MutableTransferResults } from '../../xfer/TransferResults.js';
|
|
5
|
+
import type Label from '#cli/cs/labels/Label.js';
|
|
6
|
+
import { canonicalize, prepareLabel } from './labelHelpers.js';
|
|
7
|
+
|
|
8
|
+
export async function updateIfNecessary(
|
|
9
|
+
ctx: Ctx,
|
|
10
|
+
uid: string,
|
|
11
|
+
localLabel: Record<string, unknown>,
|
|
12
|
+
remoteLabel: Label | undefined,
|
|
13
|
+
results: MutableTransferResults,
|
|
14
|
+
) {
|
|
15
|
+
if (!remoteLabel) {
|
|
16
|
+
// If we don't have remote data, err on the side of updating
|
|
17
|
+
const res = (await ctx.cs.client.PUT('/v3/labels/{label_uid}', {
|
|
18
|
+
body: { label: prepareLabel(localLabel) },
|
|
19
|
+
params: { path: { label_uid: uid } },
|
|
20
|
+
})) as unknown;
|
|
21
|
+
const putError = (res as { error?: unknown } | undefined)?.error;
|
|
22
|
+
ContentstackError.throwIfError(putError, `Failed to update label: ${uid}`);
|
|
23
|
+
results.updated.add(uid);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let shouldUpdate = true;
|
|
28
|
+
try {
|
|
29
|
+
shouldUpdate =
|
|
30
|
+
JSON.stringify(canonicalize(localLabel)) !==
|
|
31
|
+
JSON.stringify(canonicalize(remoteLabel));
|
|
32
|
+
} catch {
|
|
33
|
+
shouldUpdate = true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!shouldUpdate) return;
|
|
37
|
+
|
|
38
|
+
const res = (await ctx.cs.client.PUT('/v3/labels/{label_uid}', {
|
|
39
|
+
body: { label: prepareLabel(localLabel) },
|
|
40
|
+
params: { path: { label_uid: uid } },
|
|
41
|
+
})) as unknown;
|
|
42
|
+
const putError = (res as { error?: unknown } | undefined)?.error;
|
|
43
|
+
ContentstackError.throwIfError(putError, `Failed to update label: ${uid}`);
|
|
44
|
+
results.updated.add(uid);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function createLabel(
|
|
48
|
+
ctx: Ctx,
|
|
49
|
+
localLabel: Record<string, unknown>,
|
|
50
|
+
results: MutableTransferResults,
|
|
51
|
+
): Promise<string | null> {
|
|
52
|
+
const res = (await ctx.cs.client.POST('/v3/labels', {
|
|
53
|
+
body: { label: prepareLabel(localLabel) },
|
|
54
|
+
})) as unknown;
|
|
55
|
+
|
|
56
|
+
const postError = (res as { error?: unknown } | undefined)?.error;
|
|
57
|
+
const labelName = typeof localLabel.name === 'string' ? localLabel.name : '';
|
|
58
|
+
ContentstackError.throwIfError(
|
|
59
|
+
postError,
|
|
60
|
+
`Failed to create label: ${labelName}`,
|
|
61
|
+
);
|
|
62
|
+
const postData = (res as { data?: unknown } | undefined)?.data;
|
|
63
|
+
let createdUid: string | null = null;
|
|
64
|
+
if (isRecord(postData)) {
|
|
65
|
+
const pd = postData;
|
|
66
|
+
if (isRecord(pd.label)) {
|
|
67
|
+
const labelObj = pd.label;
|
|
68
|
+
if (typeof labelObj.uid === 'string') createdUid = labelObj.uid;
|
|
69
|
+
}
|
|
70
|
+
if (createdUid === null && typeof pd.uid === 'string') createdUid = pd.uid;
|
|
71
|
+
}
|
|
72
|
+
results.created.add(createdUid ?? '<created>');
|
|
73
|
+
return createdUid;
|
|
74
|
+
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import readYaml from '#cli/fs/readYaml.js';
|
|
2
|
-
import schemaDirectory from '../content-types/schemaDirectory.js';
|
|
3
|
-
import ContentstackError from '#cli/cs/api/ContentstackError.js';
|
|
4
2
|
import type Ctx from '../ctx/Ctx.js';
|
|
5
3
|
import { MutableTransferResults } from '../xfer/TransferResults.js';
|
|
6
4
|
import getUi from '../lib/SchemaUi.js';
|
|
@@ -8,154 +6,251 @@ import isRecord from '#cli/util/isRecord.js';
|
|
|
8
6
|
import flatten from '#cli/dto/labels/flatten.js';
|
|
9
7
|
import { isNormalizedLabels } from '#cli/dto/labels/NormalizedLabels.js';
|
|
10
8
|
import type Label from '#cli/cs/labels/Label.js';
|
|
9
|
+
import getAllLabels from '#cli/cs/labels/getAllLabels.js';
|
|
10
|
+
import { createLabel, updateIfNecessary } from './lib/labelOperations.js';
|
|
11
|
+
import { resolve } from 'node:path';
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Sort labels to ensure parents are processed before children.
|
|
15
|
+
* Labels without parents come first, then labels are sorted by dependency depth.
|
|
16
|
+
*/
|
|
17
|
+
function sortLabelsByDependency(labels: Label[]): Label[] {
|
|
18
|
+
const labelsByUid = new Map<string, Label>();
|
|
19
|
+
const sorted: Label[] = [];
|
|
20
|
+
const processed = new Set<string>();
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
// Build a map for quick lookup
|
|
23
|
+
for (const label of labels) {
|
|
24
|
+
if (isRecord(label) && typeof label.uid === 'string') {
|
|
25
|
+
labelsByUid.set(label.uid, label as Label);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
17
28
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
// Recursive function to add a label and its dependencies
|
|
30
|
+
function addLabel(label: Label) {
|
|
31
|
+
const uid = typeof label.uid === 'string' ? label.uid : '';
|
|
32
|
+
if (!uid || processed.has(uid)) return;
|
|
33
|
+
|
|
34
|
+
// First, process parent if it exists in our label set
|
|
35
|
+
const parentArray = label.parent;
|
|
36
|
+
if (Array.isArray(parentArray) && parentArray.length > 0) {
|
|
37
|
+
// Use destructuring to satisfy eslint prefer-destructuring rule
|
|
38
|
+
const [parentValue] = parentArray as unknown as readonly [
|
|
39
|
+
string,
|
|
40
|
+
...string[],
|
|
41
|
+
];
|
|
42
|
+
if (labelsByUid.has(parentValue) && !processed.has(parentValue)) {
|
|
43
|
+
const parentLabel = labelsByUid.get(parentValue);
|
|
44
|
+
if (parentLabel) addLabel(parentLabel);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Now add this label
|
|
49
|
+
sorted.push(label);
|
|
50
|
+
processed.add(uid);
|
|
24
51
|
}
|
|
25
52
|
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} else if (isRecord(data) && Array.isArray(data.labels)) {
|
|
32
|
-
// Legacy flat array format
|
|
33
|
-
flatLabels = data.labels as Label[];
|
|
34
|
-
} else if (Array.isArray(data)) {
|
|
35
|
-
// Direct array format
|
|
36
|
-
flatLabels = data as Label[];
|
|
53
|
+
// Process all labels
|
|
54
|
+
for (const label of labels) {
|
|
55
|
+
if (isRecord(label)) {
|
|
56
|
+
addLabel(label as Label);
|
|
57
|
+
}
|
|
37
58
|
}
|
|
38
59
|
|
|
60
|
+
return sorted;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default async function toContentstack(ctx: Ctx) {
|
|
64
|
+
const ui = getUi();
|
|
65
|
+
const path = resolve(ui.options.schema.schemaPath, 'labels.yaml');
|
|
66
|
+
|
|
67
|
+
const data = await loadLabelsData(path, ui);
|
|
68
|
+
if (!data) {
|
|
69
|
+
return new MutableTransferResults();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const flatLabels = extractFlatLabels(data);
|
|
39
73
|
ui.info(`Labels: read ${flatLabels.length} label(s) from ${path}`);
|
|
40
74
|
|
|
75
|
+
const {
|
|
76
|
+
localUidToName,
|
|
77
|
+
nameToRemoteUid,
|
|
78
|
+
remoteLabelsByName,
|
|
79
|
+
remoteLabelsByUid,
|
|
80
|
+
} = await prepareLabelMappings(ctx, flatLabels);
|
|
81
|
+
|
|
82
|
+
const sortedLabels = sortLabelsByDependency(flatLabels);
|
|
41
83
|
const results = new MutableTransferResults();
|
|
42
84
|
|
|
43
|
-
for (const labelRaw of
|
|
85
|
+
for (const labelRaw of sortedLabels) {
|
|
44
86
|
if (!isRecord(labelRaw)) continue;
|
|
45
|
-
// keep per-label logic in helper to reduce complexity of this function
|
|
46
87
|
|
|
47
|
-
await handleLabel(
|
|
88
|
+
await handleLabel(
|
|
89
|
+
ctx,
|
|
90
|
+
labelRaw,
|
|
91
|
+
remoteLabelsByUid,
|
|
92
|
+
remoteLabelsByName,
|
|
93
|
+
nameToRemoteUid,
|
|
94
|
+
localUidToName,
|
|
95
|
+
results,
|
|
96
|
+
);
|
|
48
97
|
}
|
|
49
98
|
|
|
50
99
|
return results;
|
|
51
100
|
}
|
|
52
101
|
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (key === 'parent_uid' && (obj[key] === null || obj[key] === undefined))
|
|
63
|
-
continue;
|
|
64
|
-
out[key] = canonicalize(obj[key]);
|
|
65
|
-
}
|
|
66
|
-
return out;
|
|
102
|
+
async function loadLabelsData(
|
|
103
|
+
path: string,
|
|
104
|
+
ui: ReturnType<typeof getUi>,
|
|
105
|
+
): Promise<unknown> {
|
|
106
|
+
try {
|
|
107
|
+
return await readYaml(path);
|
|
108
|
+
} catch {
|
|
109
|
+
ui.info(`Labels: no file at ${path}, skipping`);
|
|
110
|
+
return undefined;
|
|
67
111
|
}
|
|
68
|
-
return value;
|
|
69
112
|
}
|
|
70
113
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const res = (await ctx.cs.client.PUT('/v3/labels/{label_uid}', {
|
|
85
|
-
body: { label: prepareLabel(localLabel) },
|
|
86
|
-
params: { path: { label_uid: uid } },
|
|
87
|
-
})) as unknown;
|
|
88
|
-
const putError = (res as { error?: unknown } | undefined)?.error;
|
|
89
|
-
ContentstackError.throwIfError(putError, `Failed to update label: ${uid}`);
|
|
90
|
-
results.updated.add(uid);
|
|
91
|
-
return;
|
|
114
|
+
function extractFlatLabels(data: unknown): Label[] {
|
|
115
|
+
if (isNormalizedLabels(data)) {
|
|
116
|
+
interface LabelWithChildren {
|
|
117
|
+
children?: unknown;
|
|
118
|
+
}
|
|
119
|
+
const hasChildren = (data.labels as unknown as LabelWithChildren[]).some(
|
|
120
|
+
(l) => 'children' in l && l.children !== undefined,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
if (hasChildren) {
|
|
124
|
+
return [...flatten(data.labels)];
|
|
125
|
+
}
|
|
126
|
+
return [...data.labels] as unknown as Label[];
|
|
92
127
|
}
|
|
93
128
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
shouldUpdate =
|
|
98
|
-
JSON.stringify(canonicalize(localLabel)) !==
|
|
99
|
-
JSON.stringify(canonicalize(remoteLabel));
|
|
100
|
-
} catch {
|
|
101
|
-
shouldUpdate = true;
|
|
129
|
+
if (isRecord(data) && Array.isArray(data.labels)) {
|
|
130
|
+
return data.labels as Label[];
|
|
102
131
|
}
|
|
103
132
|
|
|
104
|
-
if (
|
|
133
|
+
if (Array.isArray(data)) {
|
|
134
|
+
return data as Label[];
|
|
135
|
+
}
|
|
105
136
|
|
|
106
|
-
|
|
107
|
-
body: { label: prepareLabel(localLabel) },
|
|
108
|
-
params: { path: { label_uid: uid } },
|
|
109
|
-
})) as unknown;
|
|
110
|
-
const putError = (res as { error?: unknown } | undefined)?.error;
|
|
111
|
-
ContentstackError.throwIfError(putError, `Failed to update label: ${uid}`);
|
|
112
|
-
results.updated.add(uid);
|
|
137
|
+
return [];
|
|
113
138
|
}
|
|
114
139
|
|
|
115
|
-
async function
|
|
116
|
-
ctx
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const pd = postData;
|
|
129
|
-
if (isRecord(pd.label)) {
|
|
130
|
-
const labelObj = pd.label;
|
|
131
|
-
if (typeof labelObj.uid === 'string') createdUid = labelObj.uid;
|
|
132
|
-
}
|
|
133
|
-
if (createdUid === null && typeof pd.uid === 'string') createdUid = pd.uid;
|
|
140
|
+
async function prepareLabelMappings(ctx: Ctx, flatLabels: Label[]) {
|
|
141
|
+
const remoteLabels = await getAllLabels(ctx.cs.client);
|
|
142
|
+
const remoteLabelsByUid = new Map<string, Label>();
|
|
143
|
+
const remoteLabelsByName = new Map<string, Label>();
|
|
144
|
+
|
|
145
|
+
for (const label of remoteLabels) {
|
|
146
|
+
remoteLabelsByUid.set(label.uid, label);
|
|
147
|
+
remoteLabelsByName.set(label.name, label);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const nameToRemoteUid = new Map<string, string>();
|
|
151
|
+
for (const [name, label] of remoteLabelsByName) {
|
|
152
|
+
nameToRemoteUid.set(name, label.uid);
|
|
134
153
|
}
|
|
135
|
-
results.created.add(createdUid ?? '<created>');
|
|
136
|
-
}
|
|
137
154
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
155
|
+
const localUidToName = new Map<string, string>();
|
|
156
|
+
for (const label of flatLabels) {
|
|
157
|
+
if (
|
|
158
|
+
isRecord(label) &&
|
|
159
|
+
typeof label.uid === 'string' &&
|
|
160
|
+
typeof label.name === 'string'
|
|
161
|
+
) {
|
|
162
|
+
localUidToName.set(label.uid, label.name);
|
|
163
|
+
}
|
|
144
164
|
}
|
|
145
|
-
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
localUidToName,
|
|
168
|
+
nameToRemoteUid,
|
|
169
|
+
remoteLabelsByName,
|
|
170
|
+
remoteLabelsByUid,
|
|
171
|
+
};
|
|
146
172
|
}
|
|
147
173
|
|
|
148
174
|
async function handleLabel(
|
|
149
175
|
ctx: Ctx,
|
|
150
176
|
labelRaw: Record<string, unknown>,
|
|
177
|
+
remoteLabelsByUid: Map<string, Label>,
|
|
178
|
+
remoteLabelsByName: Map<string, Label>,
|
|
179
|
+
nameToRemoteUid: Map<string, string>,
|
|
180
|
+
localUidToName: Map<string, string>,
|
|
151
181
|
results: MutableTransferResults,
|
|
152
182
|
) {
|
|
153
183
|
const uid = typeof labelRaw.uid === 'string' ? labelRaw.uid : '';
|
|
184
|
+
const name = typeof labelRaw.name === 'string' ? labelRaw.name : '';
|
|
185
|
+
|
|
186
|
+
const preparedLabel = translateParentReference(
|
|
187
|
+
labelRaw,
|
|
188
|
+
localUidToName,
|
|
189
|
+
nameToRemoteUid,
|
|
190
|
+
);
|
|
154
191
|
|
|
155
|
-
|
|
156
|
-
|
|
192
|
+
// First try to find by UID (exact match from same stack)
|
|
193
|
+
if (uid.length > 0 && remoteLabelsByUid.has(uid)) {
|
|
194
|
+
const remoteLabel = remoteLabelsByUid.get(uid);
|
|
195
|
+
await updateIfNecessary(ctx, uid, preparedLabel, remoteLabel, results);
|
|
157
196
|
return;
|
|
158
197
|
}
|
|
159
198
|
|
|
160
|
-
|
|
199
|
+
// Then try to find by name (for cross-stack scenarios)
|
|
200
|
+
if (name.length > 0 && remoteLabelsByName.has(name)) {
|
|
201
|
+
const remoteLabel = remoteLabelsByName.get(name);
|
|
202
|
+
if (!remoteLabel) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
await updateIfNecessary(
|
|
206
|
+
ctx,
|
|
207
|
+
remoteLabel.uid,
|
|
208
|
+
preparedLabel,
|
|
209
|
+
remoteLabel,
|
|
210
|
+
results,
|
|
211
|
+
);
|
|
212
|
+
nameToRemoteUid.set(name, remoteLabel.uid);
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Label doesn't exist remotely, create it
|
|
217
|
+
const createdUid = await createLabel(ctx, preparedLabel, results);
|
|
218
|
+
|
|
219
|
+
if (createdUid && name) {
|
|
220
|
+
nameToRemoteUid.set(name, createdUid);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function translateParentReference(
|
|
225
|
+
labelRaw: Record<string, unknown>,
|
|
226
|
+
localUidToName: Map<string, string>,
|
|
227
|
+
nameToRemoteUid: Map<string, string>,
|
|
228
|
+
): Record<string, unknown> {
|
|
229
|
+
const parentField = labelRaw.parent;
|
|
230
|
+
if (!Array.isArray(parentField) || parentField.length === 0) {
|
|
231
|
+
return { ...labelRaw };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// TypeScript knows parentField is an array, but we need to type it properly
|
|
235
|
+
const [firstElement] = parentField as unknown[];
|
|
236
|
+
if (typeof firstElement !== 'string') {
|
|
237
|
+
return { ...labelRaw };
|
|
238
|
+
}
|
|
239
|
+
const firstParent: string = firstElement;
|
|
240
|
+
|
|
241
|
+
const parentName = localUidToName.get(firstParent);
|
|
242
|
+
|
|
243
|
+
if (!parentName || !nameToRemoteUid.has(parentName)) {
|
|
244
|
+
return { ...labelRaw };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const remoteParentUid = nameToRemoteUid.get(parentName);
|
|
248
|
+
if (!remoteParentUid) {
|
|
249
|
+
return { ...labelRaw };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
...labelRaw,
|
|
254
|
+
parent: [remoteParentUid],
|
|
255
|
+
};
|
|
161
256
|
}
|
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import getAllLabels from '#cli/cs/labels/getAllLabels.js';
|
|
2
2
|
import writeYaml from '#cli/fs/writeYaml.js';
|
|
3
3
|
import organize from '#cli/dto/labels/organize.js';
|
|
4
|
-
import schemaDirectory from '../content-types/schemaDirectory.js';
|
|
5
4
|
import { MutableTransferResults } from '../xfer/TransferResults.js';
|
|
6
5
|
import createProgressBar from '../lib/createProgressBar.js';
|
|
7
6
|
import type Ctx from '../ctx/Ctx.js';
|
|
7
|
+
import getUi from '../lib/SchemaUi.js';
|
|
8
|
+
import { resolve } from 'node:path';
|
|
8
9
|
|
|
9
10
|
export default async function toFilesystem(ctx: Ctx) {
|
|
10
|
-
const
|
|
11
|
+
const ui = getUi();
|
|
12
|
+
const {
|
|
13
|
+
options: {
|
|
14
|
+
schema: { schemaPath },
|
|
15
|
+
},
|
|
16
|
+
} = ui;
|
|
17
|
+
const labelsPath = resolve(schemaPath, 'labels.yaml');
|
|
11
18
|
const bar = createProgressBar('Labels', 1, 0);
|
|
12
19
|
|
|
13
20
|
// Fetch labels and organize them into a hierarchical structure
|
|
14
21
|
const flatLabels = await getAllLabels(ctx.cs.client);
|
|
15
22
|
const hierarchicalLabels = organize(flatLabels);
|
|
16
23
|
|
|
17
|
-
await writeYaml(
|
|
24
|
+
await writeYaml(labelsPath, { labels: hierarchicalLabels });
|
|
18
25
|
|
|
19
26
|
const result = new MutableTransferResults();
|
|
20
27
|
result.created.add('labels.yaml');
|