@open-mercato/shared 0.6.1-develop.3291.1.6fad645fd0 → 0.6.1
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/lib/crud/custom-fields-client.js +21 -18
- package/dist/lib/crud/custom-fields-client.js.map +2 -2
- package/dist/lib/frontend/progressEvents.js.map +2 -2
- package/dist/lib/version.js +1 -1
- package/dist/lib/version.js.map +1 -1
- package/package.json +3 -4
- package/src/lib/crud/__tests__/custom-fields.test.ts +15 -0
- package/src/lib/crud/custom-fields-client.ts +23 -19
- package/src/lib/frontend/progressEvents.ts +6 -0
|
@@ -18,6 +18,21 @@ function extractCustomFieldEntries(item) {
|
|
|
18
18
|
if (!trimmed) return;
|
|
19
19
|
out[`cf_${trimmed}`] = normalizeValue(rawValue);
|
|
20
20
|
};
|
|
21
|
+
const assignObject = (source) => {
|
|
22
|
+
if (!source || typeof source !== "object" || Array.isArray(source)) return;
|
|
23
|
+
for (const [key, value] of Object.entries(source)) {
|
|
24
|
+
assign(key, value);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const assignEntries = (source) => {
|
|
28
|
+
if (!Array.isArray(source)) return;
|
|
29
|
+
for (const entry of source) {
|
|
30
|
+
if (!entry || typeof entry !== "object") continue;
|
|
31
|
+
const key = typeof entry.key === "string" ? entry.key : null;
|
|
32
|
+
if (!key) continue;
|
|
33
|
+
assign(key, "value" in entry ? entry.value : void 0);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
21
36
|
for (const [rawKey, rawValue] of Object.entries(item)) {
|
|
22
37
|
if (rawKey.startsWith("cf_")) {
|
|
23
38
|
if (rawKey.endsWith("__is_multi")) continue;
|
|
@@ -26,24 +41,12 @@ function extractCustomFieldEntries(item) {
|
|
|
26
41
|
assign(rawKey.slice(3), rawValue);
|
|
27
42
|
}
|
|
28
43
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const customFields = item.customFields;
|
|
36
|
-
if (Array.isArray(customFields)) {
|
|
37
|
-
for (const entry of customFields) {
|
|
38
|
-
const key = entry && typeof entry.key === "string" ? entry.key : null;
|
|
39
|
-
if (!key) continue;
|
|
40
|
-
assign(key, "value" in entry ? entry.value : void 0);
|
|
41
|
-
}
|
|
42
|
-
} else if (customFields && typeof customFields === "object") {
|
|
43
|
-
for (const [key, value] of Object.entries(customFields)) {
|
|
44
|
-
assign(key, value);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
44
|
+
assignObject(item.customValues);
|
|
45
|
+
assignObject(item.custom_values);
|
|
46
|
+
assignObject(item.customFields);
|
|
47
|
+
assignObject(item.custom_fields);
|
|
48
|
+
assignEntries(item.customFields);
|
|
49
|
+
assignEntries(item.custom_fields);
|
|
47
50
|
return out;
|
|
48
51
|
}
|
|
49
52
|
export {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/crud/custom-fields-client.ts"],
|
|
4
|
-
"sourcesContent": ["export function extractCustomFieldEntries(item: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n if (!item || typeof item !== 'object') return out\n\n const normalizeValue = (value: unknown): unknown => {\n if (Array.isArray(value)) return value\n if (typeof value !== 'string') return value\n const trimmed = value.trim()\n if (trimmed.startsWith('{') && trimmed.endsWith('}')) {\n const inner = trimmed.slice(1, -1).trim()\n if (!inner) return []\n return inner.split(/[\\s,]+/).map((entry) => entry.trim()).filter(Boolean)\n }\n return trimmed\n }\n\n const assign = (rawKey: unknown, rawValue: unknown) => {\n if (typeof rawKey !== 'string') return\n const trimmed = rawKey.trim()\n if (!trimmed) return\n out[`cf_${trimmed}`] = normalizeValue(rawValue)\n }\n\n
|
|
5
|
-
"mappings": "AAAO,SAAS,0BAA0B,MAAwD;AAChG,QAAM,MAA+B,CAAC;AACtC,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAE9C,QAAM,iBAAiB,CAAC,UAA4B;AAClD,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,QAAI,OAAO,UAAU,SAAU,QAAO;AACtC,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AACpD,YAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE,EAAE,KAAK;AACxC,UAAI,CAAC,MAAO,QAAO,CAAC;AACpB,aAAO,MAAM,MAAM,QAAQ,EAAE,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO;AAAA,IAC1E;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,CAAC,QAAiB,aAAsB;AACrD,QAAI,OAAO,WAAW,SAAU;AAChC,UAAM,UAAU,OAAO,KAAK;AAC5B,QAAI,CAAC,QAAS;AACd,QAAI,MAAM,OAAO,EAAE,IAAI,eAAe,QAAQ;AAAA,EAChD;AAEA,
|
|
4
|
+
"sourcesContent": ["export function extractCustomFieldEntries(item: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n if (!item || typeof item !== 'object') return out\n\n const normalizeValue = (value: unknown): unknown => {\n if (Array.isArray(value)) return value\n if (typeof value !== 'string') return value\n const trimmed = value.trim()\n if (trimmed.startsWith('{') && trimmed.endsWith('}')) {\n const inner = trimmed.slice(1, -1).trim()\n if (!inner) return []\n return inner.split(/[\\s,]+/).map((entry) => entry.trim()).filter(Boolean)\n }\n return trimmed\n }\n\n const assign = (rawKey: unknown, rawValue: unknown) => {\n if (typeof rawKey !== 'string') return\n const trimmed = rawKey.trim()\n if (!trimmed) return\n out[`cf_${trimmed}`] = normalizeValue(rawValue)\n }\n\n const assignObject = (source: unknown) => {\n if (!source || typeof source !== 'object' || Array.isArray(source)) return\n for (const [key, value] of Object.entries(source as Record<string, unknown>)) {\n assign(key, value)\n }\n }\n\n const assignEntries = (source: unknown) => {\n if (!Array.isArray(source)) return\n for (const entry of source as Array<Record<string, unknown>>) {\n if (!entry || typeof entry !== 'object') continue\n const key = typeof entry.key === 'string' ? entry.key : null\n if (!key) continue\n assign(key, 'value' in entry ? (entry as any).value : undefined)\n }\n }\n\n for (const [rawKey, rawValue] of Object.entries(item)) {\n if (rawKey.startsWith('cf_')) {\n if (rawKey.endsWith('__is_multi')) continue\n out[rawKey] = normalizeValue(rawValue)\n } else if (rawKey.startsWith('cf:')) {\n assign(rawKey.slice(3), rawValue)\n }\n }\n\n assignObject((item as any).customValues)\n assignObject((item as any).custom_values)\n assignObject((item as any).customFields)\n assignObject((item as any).custom_fields)\n assignEntries((item as any).customFields)\n assignEntries((item as any).custom_fields)\n\n return out\n}\n"],
|
|
5
|
+
"mappings": "AAAO,SAAS,0BAA0B,MAAwD;AAChG,QAAM,MAA+B,CAAC;AACtC,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;AAE9C,QAAM,iBAAiB,CAAC,UAA4B;AAClD,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO;AACjC,QAAI,OAAO,UAAU,SAAU,QAAO;AACtC,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,SAAS,GAAG,GAAG;AACpD,YAAM,QAAQ,QAAQ,MAAM,GAAG,EAAE,EAAE,KAAK;AACxC,UAAI,CAAC,MAAO,QAAO,CAAC;AACpB,aAAO,MAAM,MAAM,QAAQ,EAAE,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO;AAAA,IAC1E;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,CAAC,QAAiB,aAAsB;AACrD,QAAI,OAAO,WAAW,SAAU;AAChC,UAAM,UAAU,OAAO,KAAK;AAC5B,QAAI,CAAC,QAAS;AACd,QAAI,MAAM,OAAO,EAAE,IAAI,eAAe,QAAQ;AAAA,EAChD;AAEA,QAAM,eAAe,CAAC,WAAoB;AACxC,QAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,EAAG;AACpE,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAiC,GAAG;AAC5E,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,WAAoB;AACzC,QAAI,CAAC,MAAM,QAAQ,MAAM,EAAG;AAC5B,eAAW,SAAS,QAA0C;AAC5D,UAAI,CAAC,SAAS,OAAO,UAAU,SAAU;AACzC,YAAM,MAAM,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM;AACxD,UAAI,CAAC,IAAK;AACV,aAAO,KAAK,WAAW,QAAS,MAAc,QAAQ,MAAS;AAAA,IACjE;AAAA,EACF;AAEA,aAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,QAAQ,IAAI,GAAG;AACrD,QAAI,OAAO,WAAW,KAAK,GAAG;AAC5B,UAAI,OAAO,SAAS,YAAY,EAAG;AACnC,UAAI,MAAM,IAAI,eAAe,QAAQ;AAAA,IACvC,WAAW,OAAO,WAAW,KAAK,GAAG;AACnC,aAAO,OAAO,MAAM,CAAC,GAAG,QAAQ;AAAA,IAClC;AAAA,EACF;AAEA,eAAc,KAAa,YAAY;AACvC,eAAc,KAAa,aAAa;AACxC,eAAc,KAAa,YAAY;AACvC,eAAc,KAAa,aAAa;AACxC,gBAAe,KAAa,YAAY;AACxC,gBAAe,KAAa,aAAa;AAEzC,SAAO;AACT;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/frontend/progressEvents.ts"],
|
|
4
|
-
"sourcesContent": ["export const PROGRESS_DOM_EVENTS = {\n UPDATE: 'om:progress:update',\n COMPLETE: 'om:progress:complete',\n ERROR: 'om:progress:error',\n CANCELLED: 'om:progress:cancelled',\n} as const\n\nexport type ProgressUpdateDetail = {\n jobId: string\n jobType: string\n name: string\n progressPercent: number\n processedCount: number\n totalCount?: number | null\n etaSeconds?: number | null\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'\n}\n\nexport function emitProgressUpdate(detail: ProgressUpdateDetail): void {\n if (typeof window === 'undefined' || typeof CustomEvent === 'undefined') return\n window.dispatchEvent(new CustomEvent(PROGRESS_DOM_EVENTS.UPDATE, { detail }))\n}\n\nexport function emitProgressComplete(jobId: string, jobType: string): void {\n if (typeof window === 'undefined' || typeof CustomEvent === 'undefined') return\n window.dispatchEvent(new CustomEvent(PROGRESS_DOM_EVENTS.COMPLETE, { detail: { jobId, jobType } }))\n}\n\nexport function emitProgressError(jobId: string, errorMessage: string): void {\n if (typeof window === 'undefined' || typeof CustomEvent === 'undefined') return\n window.dispatchEvent(new CustomEvent(PROGRESS_DOM_EVENTS.ERROR, { detail: { jobId, errorMessage } }))\n}\n\nexport function subscribeProgressUpdate(handler: (detail: ProgressUpdateDetail) => void): () => void {\n if (typeof window === 'undefined') return () => {}\n const listener = (event: Event) => handler((event as CustomEvent<ProgressUpdateDetail>).detail)\n window.addEventListener(PROGRESS_DOM_EVENTS.UPDATE, listener)\n return () => window.removeEventListener(PROGRESS_DOM_EVENTS.UPDATE, listener)\n}\n\nexport function subscribeProgressComplete(handler: (detail: { jobId: string; jobType: string }) => void): () => void {\n if (typeof window === 'undefined') return () => {}\n const listener = (event: Event) => handler((event as CustomEvent<{ jobId: string; jobType: string }>).detail)\n window.addEventListener(PROGRESS_DOM_EVENTS.COMPLETE, listener)\n return () => window.removeEventListener(PROGRESS_DOM_EVENTS.COMPLETE, listener)\n}\n"],
|
|
5
|
-
"mappings": "AAAO,MAAM,sBAAsB;AAAA,EACjC,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,WAAW;AACb;
|
|
4
|
+
"sourcesContent": ["export const PROGRESS_DOM_EVENTS = {\n UPDATE: 'om:progress:update',\n COMPLETE: 'om:progress:complete',\n ERROR: 'om:progress:error',\n CANCELLED: 'om:progress:cancelled',\n} as const\n\nexport type ProgressUpdateDetail = {\n jobId: string\n jobType: string\n name: string\n description?: string | null\n meta?: Record<string, unknown> | null\n progressPercent: number\n processedCount: number\n totalCount?: number | null\n etaSeconds?: number | null\n status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'\n cancellable?: boolean\n startedAt?: string | null\n finishedAt?: string | null\n errorMessage?: string | null\n}\n\nexport function emitProgressUpdate(detail: ProgressUpdateDetail): void {\n if (typeof window === 'undefined' || typeof CustomEvent === 'undefined') return\n window.dispatchEvent(new CustomEvent(PROGRESS_DOM_EVENTS.UPDATE, { detail }))\n}\n\nexport function emitProgressComplete(jobId: string, jobType: string): void {\n if (typeof window === 'undefined' || typeof CustomEvent === 'undefined') return\n window.dispatchEvent(new CustomEvent(PROGRESS_DOM_EVENTS.COMPLETE, { detail: { jobId, jobType } }))\n}\n\nexport function emitProgressError(jobId: string, errorMessage: string): void {\n if (typeof window === 'undefined' || typeof CustomEvent === 'undefined') return\n window.dispatchEvent(new CustomEvent(PROGRESS_DOM_EVENTS.ERROR, { detail: { jobId, errorMessage } }))\n}\n\nexport function subscribeProgressUpdate(handler: (detail: ProgressUpdateDetail) => void): () => void {\n if (typeof window === 'undefined') return () => {}\n const listener = (event: Event) => handler((event as CustomEvent<ProgressUpdateDetail>).detail)\n window.addEventListener(PROGRESS_DOM_EVENTS.UPDATE, listener)\n return () => window.removeEventListener(PROGRESS_DOM_EVENTS.UPDATE, listener)\n}\n\nexport function subscribeProgressComplete(handler: (detail: { jobId: string; jobType: string }) => void): () => void {\n if (typeof window === 'undefined') return () => {}\n const listener = (event: Event) => handler((event as CustomEvent<{ jobId: string; jobType: string }>).detail)\n window.addEventListener(PROGRESS_DOM_EVENTS.COMPLETE, listener)\n return () => window.removeEventListener(PROGRESS_DOM_EVENTS.COMPLETE, listener)\n}\n"],
|
|
5
|
+
"mappings": "AAAO,MAAM,sBAAsB;AAAA,EACjC,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,WAAW;AACb;AAmBO,SAAS,mBAAmB,QAAoC;AACrE,MAAI,OAAO,WAAW,eAAe,OAAO,gBAAgB,YAAa;AACzE,SAAO,cAAc,IAAI,YAAY,oBAAoB,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC9E;AAEO,SAAS,qBAAqB,OAAe,SAAuB;AACzE,MAAI,OAAO,WAAW,eAAe,OAAO,gBAAgB,YAAa;AACzE,SAAO,cAAc,IAAI,YAAY,oBAAoB,UAAU,EAAE,QAAQ,EAAE,OAAO,QAAQ,EAAE,CAAC,CAAC;AACpG;AAEO,SAAS,kBAAkB,OAAe,cAA4B;AAC3E,MAAI,OAAO,WAAW,eAAe,OAAO,gBAAgB,YAAa;AACzE,SAAO,cAAc,IAAI,YAAY,oBAAoB,OAAO,EAAE,QAAQ,EAAE,OAAO,aAAa,EAAE,CAAC,CAAC;AACtG;AAEO,SAAS,wBAAwB,SAA6D;AACnG,MAAI,OAAO,WAAW,YAAa,QAAO,MAAM;AAAA,EAAC;AACjD,QAAM,WAAW,CAAC,UAAiB,QAAS,MAA4C,MAAM;AAC9F,SAAO,iBAAiB,oBAAoB,QAAQ,QAAQ;AAC5D,SAAO,MAAM,OAAO,oBAAoB,oBAAoB,QAAQ,QAAQ;AAC9E;AAEO,SAAS,0BAA0B,SAA2E;AACnH,MAAI,OAAO,WAAW,YAAa,QAAO,MAAM;AAAA,EAAC;AACjD,QAAM,WAAW,CAAC,UAAiB,QAAS,MAA0D,MAAM;AAC5G,SAAO,iBAAiB,oBAAoB,UAAU,QAAQ;AAC9D,SAAO,MAAM,OAAO,oBAAoB,oBAAoB,UAAU,QAAQ;AAChF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/lib/version.js
CHANGED
package/dist/lib/version.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/version.ts"],
|
|
4
|
-
"sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.6.1
|
|
4
|
+
"sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.6.1'\nexport const appVersion = APP_VERSION\n"],
|
|
5
5
|
"mappings": "AACO,MAAM,cAAc;AACpB,MAAM,aAAa;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/shared",
|
|
3
|
-
"version": "0.6.1
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"@mikro-orm/core": "^7.0.15",
|
|
93
93
|
"@mikro-orm/decorators": "^7.0.15",
|
|
94
94
|
"@mikro-orm/postgresql": "^7.0.15",
|
|
95
|
-
"@open-mercato/cache": "0.6.1
|
|
95
|
+
"@open-mercato/cache": "0.6.1",
|
|
96
96
|
"dotenv": "^17.4.2",
|
|
97
97
|
"rate-limiter-flexible": "^11.1.0",
|
|
98
98
|
"reflect-metadata": "^0.2.2",
|
|
@@ -112,6 +112,5 @@
|
|
|
112
112
|
"type": "git",
|
|
113
113
|
"url": "https://github.com/open-mercato/open-mercato",
|
|
114
114
|
"directory": "packages/shared"
|
|
115
|
-
}
|
|
116
|
-
"stableVersion": "0.6.0"
|
|
115
|
+
}
|
|
117
116
|
}
|
|
@@ -145,6 +145,21 @@ describe('extractAllCustomFieldEntries', () => {
|
|
|
145
145
|
cf_existing: 'foo',
|
|
146
146
|
})
|
|
147
147
|
})
|
|
148
|
+
|
|
149
|
+
it('reads snake-case custom field containers', () => {
|
|
150
|
+
const item = {
|
|
151
|
+
custom_values: { api_url: 'https://snake.example', priority: 7 },
|
|
152
|
+
custom_fields: [
|
|
153
|
+
{ key: 'array_key', value: 'array-value' },
|
|
154
|
+
],
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
expect(extractAllCustomFieldEntries(item)).toEqual({
|
|
158
|
+
cf_api_url: 'https://snake.example',
|
|
159
|
+
cf_priority: 7,
|
|
160
|
+
cf_array_key: 'array-value',
|
|
161
|
+
})
|
|
162
|
+
})
|
|
148
163
|
})
|
|
149
164
|
|
|
150
165
|
describe('loadCustomFieldValues (encryption)', () => {
|
|
@@ -21,34 +21,38 @@ export function extractCustomFieldEntries(item: Record<string, unknown>): Record
|
|
|
21
21
|
out[`cf_${trimmed}`] = normalizeValue(rawValue)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
out[rawKey] = normalizeValue(rawValue)
|
|
28
|
-
} else if (rawKey.startsWith('cf:')) {
|
|
29
|
-
assign(rawKey.slice(3), rawValue)
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const customValues = (item as any).customValues
|
|
34
|
-
if (customValues && typeof customValues === 'object' && !Array.isArray(customValues)) {
|
|
35
|
-
for (const [key, value] of Object.entries(customValues as Record<string, unknown>)) {
|
|
24
|
+
const assignObject = (source: unknown) => {
|
|
25
|
+
if (!source || typeof source !== 'object' || Array.isArray(source)) return
|
|
26
|
+
for (const [key, value] of Object.entries(source as Record<string, unknown>)) {
|
|
36
27
|
assign(key, value)
|
|
37
28
|
}
|
|
38
29
|
}
|
|
39
30
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
for (const entry of
|
|
43
|
-
|
|
31
|
+
const assignEntries = (source: unknown) => {
|
|
32
|
+
if (!Array.isArray(source)) return
|
|
33
|
+
for (const entry of source as Array<Record<string, unknown>>) {
|
|
34
|
+
if (!entry || typeof entry !== 'object') continue
|
|
35
|
+
const key = typeof entry.key === 'string' ? entry.key : null
|
|
44
36
|
if (!key) continue
|
|
45
37
|
assign(key, 'value' in entry ? (entry as any).value : undefined)
|
|
46
38
|
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (const [rawKey, rawValue] of Object.entries(item)) {
|
|
42
|
+
if (rawKey.startsWith('cf_')) {
|
|
43
|
+
if (rawKey.endsWith('__is_multi')) continue
|
|
44
|
+
out[rawKey] = normalizeValue(rawValue)
|
|
45
|
+
} else if (rawKey.startsWith('cf:')) {
|
|
46
|
+
assign(rawKey.slice(3), rawValue)
|
|
50
47
|
}
|
|
51
48
|
}
|
|
52
49
|
|
|
50
|
+
assignObject((item as any).customValues)
|
|
51
|
+
assignObject((item as any).custom_values)
|
|
52
|
+
assignObject((item as any).customFields)
|
|
53
|
+
assignObject((item as any).custom_fields)
|
|
54
|
+
assignEntries((item as any).customFields)
|
|
55
|
+
assignEntries((item as any).custom_fields)
|
|
56
|
+
|
|
53
57
|
return out
|
|
54
58
|
}
|
|
@@ -9,11 +9,17 @@ export type ProgressUpdateDetail = {
|
|
|
9
9
|
jobId: string
|
|
10
10
|
jobType: string
|
|
11
11
|
name: string
|
|
12
|
+
description?: string | null
|
|
13
|
+
meta?: Record<string, unknown> | null
|
|
12
14
|
progressPercent: number
|
|
13
15
|
processedCount: number
|
|
14
16
|
totalCount?: number | null
|
|
15
17
|
etaSeconds?: number | null
|
|
16
18
|
status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'
|
|
19
|
+
cancellable?: boolean
|
|
20
|
+
startedAt?: string | null
|
|
21
|
+
finishedAt?: string | null
|
|
22
|
+
errorMessage?: string | null
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
export function emitProgressUpdate(detail: ProgressUpdateDetail): void {
|