@arkebcacy/beacon-cli-temp 0.1.4 → 0.1.6
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/entries/getEntryLocales.d.ts.map +1 -1
- package/dist/cs/entries/getEntryLocales.js +23 -10
- package/dist/cs/entries/getEntryLocales.js.map +1 -1
- package/dist/cs/labels/Label.d.ts +8 -0
- package/dist/cs/labels/Label.d.ts.map +1 -0
- package/dist/cs/labels/Label.js +7 -0
- package/dist/cs/labels/Label.js.map +1 -0
- package/dist/cs/labels/getAllLabels.d.ts +4 -0
- package/dist/cs/labels/getAllLabels.d.ts.map +1 -0
- package/dist/cs/labels/getAllLabels.js +37 -0
- package/dist/cs/labels/getAllLabels.js.map +1 -0
- package/dist/dto/entry/beaconReplacer/lib/mapItemPathToAsset.d.ts.map +1 -1
- package/dist/dto/entry/beaconReplacer/lib/mapItemPathToAsset.js +5 -1
- package/dist/dto/entry/beaconReplacer/lib/mapItemPathToAsset.js.map +1 -1
- package/dist/dto/labels/NormalizedLabels.d.ts +13 -0
- package/dist/dto/labels/NormalizedLabels.d.ts.map +1 -0
- package/dist/dto/labels/NormalizedLabels.js +25 -0
- package/dist/dto/labels/NormalizedLabels.js.map +1 -0
- package/dist/dto/labels/flatten.d.ts +4 -0
- package/dist/dto/labels/flatten.d.ts.map +1 -0
- package/dist/dto/labels/flatten.js +18 -0
- package/dist/dto/labels/flatten.js.map +1 -0
- package/dist/dto/labels/organize.d.ts +4 -0
- package/dist/dto/labels/organize.d.ts.map +1 -0
- package/dist/dto/labels/organize.js +40 -0
- package/dist/dto/labels/organize.js.map +1 -0
- package/dist/schema/entries/toFilesystem.d.ts.map +1 -1
- package/dist/schema/entries/toFilesystem.js +24 -6
- package/dist/schema/entries/toFilesystem.js.map +1 -1
- package/dist/schema/labels/toContentstack.d.ts +4 -0
- package/dist/schema/labels/toContentstack.d.ts.map +1 -0
- package/dist/schema/labels/toContentstack.js +136 -0
- package/dist/schema/labels/toContentstack.js.map +1 -0
- package/dist/schema/labels/toFilesystem.d.ts +4 -0
- package/dist/schema/labels/toFilesystem.d.ts.map +1 -0
- package/dist/schema/labels/toFilesystem.js +19 -0
- package/dist/schema/labels/toFilesystem.js.map +1 -0
- package/dist/schema/lib/createProgressBar.d.ts +1 -1
- package/dist/schema/lib/createProgressBar.d.ts.map +1 -1
- package/dist/schema/lib/createProgressBar.js +11 -1
- package/dist/schema/lib/createProgressBar.js.map +1 -1
- package/dist/schema/lib/pullModules.d.ts.map +1 -1
- package/dist/schema/lib/pullModules.js +2 -0
- package/dist/schema/lib/pullModules.js.map +1 -1
- package/dist/schema/push.d.ts.map +1 -1
- package/dist/schema/push.js +2 -0
- package/dist/schema/push.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/cs/entries/getEntryLocales.ts +28 -19
- package/src/cs/labels/Label.ts +16 -0
- package/src/cs/labels/getAllLabels.ts +43 -0
- package/src/dto/entry/beaconReplacer/lib/mapItemPathToAsset.ts +9 -1
- package/src/dto/labels/NormalizedLabels.ts +47 -0
- package/src/dto/labels/flatten.test.ts +118 -0
- package/src/dto/labels/flatten.ts +27 -0
- package/src/dto/labels/organize.test.ts +131 -0
- package/src/dto/labels/organize.ts +57 -0
- package/src/schema/entries/toFilesystem.ts +26 -6
- package/src/schema/labels/toContentstack.ts +161 -0
- package/src/schema/labels/toFilesystem.ts +23 -0
- package/src/schema/lib/createProgressBar.ts +10 -2
- package/src/schema/lib/pullModules.ts +2 -0
- package/src/schema/push.ts +2 -0
|
@@ -0,0 +1,161 @@
|
|
|
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
|
+
import type Ctx from '../ctx/Ctx.js';
|
|
5
|
+
import { MutableTransferResults } from '../xfer/TransferResults.js';
|
|
6
|
+
import getUi from '../lib/SchemaUi.js';
|
|
7
|
+
import isRecord from '#cli/util/isRecord.js';
|
|
8
|
+
import flatten from '#cli/dto/labels/flatten.js';
|
|
9
|
+
import { isNormalizedLabels } from '#cli/dto/labels/NormalizedLabels.js';
|
|
10
|
+
import type Label from '#cli/cs/labels/Label.js';
|
|
11
|
+
|
|
12
|
+
export default async function toContentstack(ctx: Ctx) {
|
|
13
|
+
const directory = schemaDirectory();
|
|
14
|
+
const path = `${directory}/labels.yaml`;
|
|
15
|
+
|
|
16
|
+
const ui = getUi();
|
|
17
|
+
|
|
18
|
+
let data: unknown;
|
|
19
|
+
try {
|
|
20
|
+
data = await readYaml(path);
|
|
21
|
+
} catch {
|
|
22
|
+
ui.info(`Labels: no file at ${path}, skipping`);
|
|
23
|
+
return new MutableTransferResults();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Support both hierarchical and flat label structures
|
|
27
|
+
let flatLabels: Label[] = [];
|
|
28
|
+
if (isNormalizedLabels(data)) {
|
|
29
|
+
// Hierarchical structure - flatten it first
|
|
30
|
+
flatLabels = [...flatten(data.labels)];
|
|
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[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
ui.info(`Labels: read ${flatLabels.length} label(s) from ${path}`);
|
|
40
|
+
|
|
41
|
+
const results = new MutableTransferResults();
|
|
42
|
+
|
|
43
|
+
for (const labelRaw of flatLabels) {
|
|
44
|
+
if (!isRecord(labelRaw)) continue;
|
|
45
|
+
// keep per-label logic in helper to reduce complexity of this function
|
|
46
|
+
|
|
47
|
+
await handleLabel(ctx, labelRaw, results);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return results;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function canonicalize(value: unknown): unknown {
|
|
54
|
+
if (Array.isArray(value)) return value.map(canonicalize);
|
|
55
|
+
if (isRecord(value)) {
|
|
56
|
+
const obj = value;
|
|
57
|
+
const out: Record<string, unknown> = {};
|
|
58
|
+
for (const key of Object.keys(obj).sort()) {
|
|
59
|
+
if (key === 'uid' || key === 'created_at' || key === 'updated_at')
|
|
60
|
+
continue;
|
|
61
|
+
// Normalize parent_uid: skip if null or undefined
|
|
62
|
+
if (key === 'parent_uid' && (obj[key] === null || obj[key] === undefined))
|
|
63
|
+
continue;
|
|
64
|
+
out[key] = canonicalize(obj[key]);
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function updateIfNecessary(
|
|
72
|
+
ctx: Ctx,
|
|
73
|
+
uid: string,
|
|
74
|
+
localLabel: Record<string, unknown>,
|
|
75
|
+
results: MutableTransferResults,
|
|
76
|
+
) {
|
|
77
|
+
const remoteRes = (await ctx.cs.client.GET('/v3/labels/{label_uid}', {
|
|
78
|
+
params: { path: { label_uid: uid } },
|
|
79
|
+
})) as unknown;
|
|
80
|
+
const remoteData = (remoteRes as { data?: unknown } | undefined)?.data;
|
|
81
|
+
|
|
82
|
+
if (!isRecord(remoteData) || !isRecord(remoteData.label)) {
|
|
83
|
+
// If we can't parse remote data, err on the side of updating
|
|
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;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const remoteLabel = remoteData.label;
|
|
95
|
+
let shouldUpdate = true;
|
|
96
|
+
try {
|
|
97
|
+
shouldUpdate =
|
|
98
|
+
JSON.stringify(canonicalize(localLabel)) !==
|
|
99
|
+
JSON.stringify(canonicalize(remoteLabel));
|
|
100
|
+
} catch {
|
|
101
|
+
shouldUpdate = true;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!shouldUpdate) return;
|
|
105
|
+
|
|
106
|
+
const res = (await ctx.cs.client.PUT('/v3/labels/{label_uid}', {
|
|
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);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function createLabel(
|
|
116
|
+
ctx: Ctx,
|
|
117
|
+
localLabel: Record<string, unknown>,
|
|
118
|
+
results: MutableTransferResults,
|
|
119
|
+
) {
|
|
120
|
+
const res = (await ctx.cs.client.POST('/v3/labels', {
|
|
121
|
+
body: { label: prepareLabel(localLabel) },
|
|
122
|
+
})) as unknown;
|
|
123
|
+
const postError = (res as { error?: unknown } | undefined)?.error;
|
|
124
|
+
ContentstackError.throwIfError(postError, `Failed to create label`);
|
|
125
|
+
const postData = (res as { data?: unknown } | undefined)?.data;
|
|
126
|
+
let createdUid: string | null = null;
|
|
127
|
+
if (isRecord(postData)) {
|
|
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;
|
|
134
|
+
}
|
|
135
|
+
results.created.add(createdUid ?? '<created>');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Prepare label for API by removing parent_uid if null
|
|
139
|
+
function prepareLabel(label: Record<string, unknown>): Record<string, unknown> {
|
|
140
|
+
const { parent_uid, ...rest } = label;
|
|
141
|
+
// Only include parent_uid if it's a non-null string
|
|
142
|
+
if (typeof parent_uid === 'string') {
|
|
143
|
+
return { ...rest, parent_uid };
|
|
144
|
+
}
|
|
145
|
+
return rest;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function handleLabel(
|
|
149
|
+
ctx: Ctx,
|
|
150
|
+
labelRaw: Record<string, unknown>,
|
|
151
|
+
results: MutableTransferResults,
|
|
152
|
+
) {
|
|
153
|
+
const uid = typeof labelRaw.uid === 'string' ? labelRaw.uid : '';
|
|
154
|
+
|
|
155
|
+
if (uid.length) {
|
|
156
|
+
await updateIfNecessary(ctx, uid, labelRaw, results);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
await createLabel(ctx, labelRaw, results);
|
|
161
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import getAllLabels from '#cli/cs/labels/getAllLabels.js';
|
|
2
|
+
import writeYaml from '#cli/fs/writeYaml.js';
|
|
3
|
+
import organize from '#cli/dto/labels/organize.js';
|
|
4
|
+
import schemaDirectory from '../content-types/schemaDirectory.js';
|
|
5
|
+
import { MutableTransferResults } from '../xfer/TransferResults.js';
|
|
6
|
+
import createProgressBar from '../lib/createProgressBar.js';
|
|
7
|
+
import type Ctx from '../ctx/Ctx.js';
|
|
8
|
+
|
|
9
|
+
export default async function toFilesystem(ctx: Ctx) {
|
|
10
|
+
const directory = schemaDirectory();
|
|
11
|
+
const bar = createProgressBar('Labels', 1, 0);
|
|
12
|
+
|
|
13
|
+
// Fetch labels and organize them into a hierarchical structure
|
|
14
|
+
const flatLabels = await getAllLabels(ctx.cs.client);
|
|
15
|
+
const hierarchicalLabels = organize(flatLabels);
|
|
16
|
+
|
|
17
|
+
await writeYaml(`${directory}/labels.yaml`, { labels: hierarchicalLabels });
|
|
18
|
+
|
|
19
|
+
const result = new MutableTransferResults();
|
|
20
|
+
result.created.add('labels.yaml');
|
|
21
|
+
bar.increment();
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
@@ -2,8 +2,16 @@ import getUi from './SchemaUi.js';
|
|
|
2
2
|
|
|
3
3
|
export default function createProgressBar(
|
|
4
4
|
name: string,
|
|
5
|
-
...indicies: readonly ReadonlyMap<unknown, unknown>[]
|
|
5
|
+
...indicies: readonly (ReadonlyMap<unknown, unknown> | number)[]
|
|
6
6
|
) {
|
|
7
|
-
const
|
|
7
|
+
const sizes = indicies.map((x) => {
|
|
8
|
+
if (typeof x === 'number') return x;
|
|
9
|
+
try {
|
|
10
|
+
return [...x.keys()].length;
|
|
11
|
+
} catch {
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
const totalSize = sizes.reduce((a, b) => a + b, 0);
|
|
8
16
|
return getUi().createProgressBar(name, totalSize);
|
|
9
17
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ContentType } from '#cli/cs/content-types/Types.js';
|
|
2
2
|
import assets from '../assets/toFilesystem.js';
|
|
3
3
|
import contentTypes from '../content-types/toFilesystem.js';
|
|
4
|
+
import labels from '../labels/toFilesystem.js';
|
|
4
5
|
import type Ctx from '../ctx/Ctx.js';
|
|
5
6
|
import clean from '../entries/clean.js';
|
|
6
7
|
import entries from '../entries/toFilesystem.js';
|
|
@@ -15,6 +16,7 @@ export default async function* pullModules(
|
|
|
15
16
|
yield ['Assets', assets(ctx)];
|
|
16
17
|
yield ['Global Fields', globalFields(ctx)];
|
|
17
18
|
yield ['Taxonomies', taxonomies(ctx)];
|
|
19
|
+
yield ['Labels', labels(ctx)];
|
|
18
20
|
yield ['Content Types', contentTypes(ctx)];
|
|
19
21
|
|
|
20
22
|
const summary = summarizeContentTypes(ctx);
|
package/src/schema/push.ts
CHANGED
|
@@ -11,6 +11,7 @@ import PushResults from './lib/PushResults.js';
|
|
|
11
11
|
import getUi from './lib/SchemaUi.js';
|
|
12
12
|
import taxonomies from './taxonomies/toContentstack.js';
|
|
13
13
|
import terms from './terms/toContentstack.js';
|
|
14
|
+
import labels from './labels/toContentstack.js';
|
|
14
15
|
|
|
15
16
|
export default async function push(client: Client) {
|
|
16
17
|
const results = new PushResults();
|
|
@@ -62,6 +63,7 @@ export default async function push(client: Client) {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
await results.set('References', updateMissedReferences(ctx));
|
|
66
|
+
await results.set('Labels', labels(ctx));
|
|
65
67
|
return results.value;
|
|
66
68
|
}
|
|
67
69
|
|