@inizioevoke/veeva-astroclm-core 1.4.4 → 1.4.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.
@@ -1,19 +1,20 @@
1
1
  import type { IVeevaConfig } from '../types';
2
2
  export interface AdditionalField {
3
3
  header: string;
4
- value?: string;
4
+ value?: any;
5
5
  property?: string;
6
6
  }
7
+ export interface AdditionalFields {
8
+ presentation?: AdditionalField[];
9
+ slides?: AdditionalField[];
10
+ shared?: AdditionalField[];
11
+ }
7
12
  interface Params {
8
13
  config: IVeevaConfig;
9
14
  deployDir: string;
10
15
  buildName: string;
11
16
  fieldsOnly?: boolean;
12
- additional?: {
13
- presentation: AdditionalField[];
14
- slides: AdditionalField[];
15
- shared: AdditionalField[];
16
- };
17
+ additionalFields?: AdditionalFields;
17
18
  }
18
- export default function ({ config, deployDir, buildName, fieldsOnly, additional }: Params): Promise<void>;
19
+ export default function ({ config, deployDir, buildName, fieldsOnly, additionalFields }: Params): Promise<void>;
19
20
  export {};
@@ -2,29 +2,32 @@ import { writeFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  import logger from '../lib/logger.js';
4
4
  import { pathToSlideZip } from '../lib/utils.js';
5
- export default async function ({ config, deployDir, buildName, fieldsOnly = false, additional }) {
5
+ export default async function ({ config, deployDir, buildName, fieldsOnly = false, additionalFields }) {
6
6
  logger.info('Creating multichannel loader CSV');
7
- const headers = fieldsOnly ? CSV_HEADERS_FIELDS_ONLY : CSV_HEADERS;
7
+ const headers = [...(fieldsOnly ? CSV_HEADERS_FIELDS_ONLY : CSV_HEADERS)];
8
+ const additional = filterAdditionalFields(config, additionalFields);
8
9
  additional?.presentation?.forEach((a) => {
9
- if (a.value || (a.property && config.presentation[a.property])) {
10
+ if (!headers.includes(a.header) && (a.value || (a.property && config.presentation[a.property] !== undefined))) {
10
11
  headers.push(a.header);
11
12
  }
12
13
  });
13
14
  additional?.slides?.forEach((a) => {
14
- if (a.value) {
15
- headers.push(a.header);
16
- }
17
- else if (a.property && config.presentation.slides) {
18
- const slide = config.presentation.slides.find((s) => {
19
- return s[a.property];
20
- });
21
- if (slide) {
15
+ if (!headers.includes(a.header)) {
16
+ if (a.value) {
22
17
  headers.push(a.header);
23
18
  }
19
+ else if (a.property && config.presentation.slides) {
20
+ const slide = config.presentation.slides.find((s) => {
21
+ return s[a.property] !== undefined;
22
+ });
23
+ if (slide) {
24
+ headers.push(a.header);
25
+ }
26
+ }
24
27
  }
25
28
  });
26
29
  additional?.shared?.forEach((a) => {
27
- if (a.value || (a.property && config.presentation.shared && config.presentation.shared[a.property])) {
30
+ if (!headers.includes(a.header) && (a.value || (a.property && config.presentation.shared && config.presentation.shared[a.property] !== undefined))) {
28
31
  headers.push(a.header);
29
32
  }
30
33
  });
@@ -48,6 +51,21 @@ export default async function ({ config, deployDir, buildName, fieldsOnly = fals
48
51
  shared && rows.push(shared);
49
52
  await writeFile(join(deployDir, `_${config.presentation.presentationId}_${buildName}.csv`), rows.map((r) => { return r.join(','); }).join('\n'), { encoding: 'utf8' });
50
53
  }
54
+ function filterAdditionalFields(config, additionalFields) {
55
+ if (!additionalFields)
56
+ return undefined;
57
+ const additional = {};
58
+ additional.presentation = additionalFields?.presentation?.filter((v, i, a) => {
59
+ return a.findIndex(x => x.header === v.header) === i && (v.value !== undefined || v.property !== undefined);
60
+ });
61
+ additional.slides = additionalFields?.slides?.filter((v, i, a) => {
62
+ return a.findIndex(x => x.header === v.header) === i && (v.value !== undefined || v.property !== undefined);
63
+ });
64
+ additional.shared = additionalFields?.shared?.filter((v, i, a) => {
65
+ return a.findIndex(x => x.header === v.header) === i && (v.value !== undefined || v.property !== undefined);
66
+ });
67
+ return additional;
68
+ }
51
69
  const VEEVA_YES = 'YES', VEEVA_NO = 'NO', VEEVA_TYPE_PRESENTATION = 'Presentation', VEEVA_TYPE_SLIDE = 'Slide', VEEVA_TYPE_SHARED = 'Shared', VEEVA_LIFECYCLE_BINDER = 'Binder Lifecycle', VEEVA_LIFECYCLE_CRM_CONTENT = 'CRM Content Lifecycle', VEEVA_IOS_RESOLUTION_DEFAULT = 'Default For Device', VEEVA_MEDIATYPE_HTML = 'HTML',
52
70
  // HEADERS
53
71
  HEADER_FIELDS_ONLY = 'Fields Only', HEADER_EXTERNAL_ID = 'external_id__v', HEADER_NAME = 'name__v', HEADER_TYPE = 'Type', HEADER_LIFECYCLE = 'lifecycle__v', HEADER_PRES_ID = 'pres.crm_presentation_id__v', HEADER_PRES_TITLE = 'pres.title__v', HEADER_PRES_PRODUCT = 'pres.product__v.name__v', HEADER_PRES_COUNTRY = 'pres.country__v.name__v', HEADER_PRES_LANGUAGE = 'pres.language__v', HEADER_PRES_CLM_CONTENT = 'pres.clm_content__v', HEADER_PRES_CLM_HIDDEN = 'pres.crm_hidden__v', HEADER_PRES_TRAINING = 'pres.crm_training__v', HEADER_PRES_CRM_TARGET = 'pres.crm_target_platform__v', HEADER_PRES_CRM_ORG = 'pres.crm_org__v.crm_org_id__v', HEADER_PRES_CRM_PRODUCT = 'pres.crm_product__v.id', // Get the Veeva ID from the URL
@@ -127,7 +145,7 @@ function createPresentationRow(headers, config, additional) {
127
145
  addColumn(headers, row, header, presentation[key]);
128
146
  }
129
147
  additional?.forEach((a) => {
130
- addColumn(headers, row, a.header, a.property ? presentation[a.property] : a.value);
148
+ addColumn(headers, row, a.header, a.value ?? presentation[a.property]);
131
149
  });
132
150
  return row;
133
151
  }
@@ -162,7 +180,7 @@ function createSlideRow(headers, config, slide, additional) {
162
180
  addColumn(headers, row, header, slide[key] ?? config.presentation.slideSettings?.[key] ?? config.slideSettings?.[key]);
163
181
  }
164
182
  additional?.forEach((a) => {
165
- addColumn(headers, row, a.header, a.property ? slide[a.property] : a.value);
183
+ addColumn(headers, row, a.header, a.value ?? slide[a.property]);
166
184
  });
167
185
  return row;
168
186
  }
@@ -189,7 +207,7 @@ function createSharedRow(headers, config, additional) {
189
207
  addColumn(headers, row, header, shared[key] ?? config.presentation.slideSettings?.[key] ?? config.slideSettings?.[key]);
190
208
  }
191
209
  additional?.forEach((a) => {
192
- addColumn(headers, row, a.header, a.property ? shared[a.property] : a.value);
210
+ addColumn(headers, row, a.header, a.value ?? shared[a.property]);
193
211
  });
194
212
  return row;
195
213
  }
@@ -1,10 +1,12 @@
1
1
  import { IVeevaConfig } from '../types';
2
+ import { type AdditionalFields } from './create-csv.js';
2
3
  interface Opts {
3
4
  root: string;
4
5
  config: IVeevaConfig;
5
6
  env: string;
6
7
  csvOnly?: boolean;
7
8
  serverPort?: number;
9
+ additionalCsvFields?: AdditionalFields;
8
10
  }
9
- export default function ({ root, config, env, csvOnly, serverPort }: Opts): Promise<void>;
11
+ export default function ({ root, config, env, csvOnly, serverPort, additionalCsvFields }: Opts): Promise<void>;
10
12
  export {};
@@ -14,7 +14,7 @@ const argv = parseArgv({
14
14
  mode: 'string',
15
15
  fieldsOnly: 'boolean'
16
16
  });
17
- export default async function ({ root, config, env, csvOnly = false, serverPort = 4320 }) {
17
+ export default async function ({ root, config, env, csvOnly = false, serverPort = 4320, additionalCsvFields }) {
18
18
  const rootDir = root ?? process.cwd();
19
19
  // we could import the astro config and see if the outDir was set but right now it's not necessary
20
20
  const astroConfig = await getAstroConfig(root);
@@ -50,7 +50,7 @@ export default async function ({ root, config, env, csvOnly = false, serverPort
50
50
  await server.stop();
51
51
  await createZips({ config, deployDir });
52
52
  }
53
- await createCsv({ config, deployDir, buildName, fieldsOnly: csvOnly });
53
+ await createCsv({ config, deployDir, buildName, fieldsOnly: csvOnly, additionalFields: additionalCsvFields });
54
54
  }
55
55
  async function getAstroConfig(root) {
56
56
  let config = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inizioevoke/veeva-astroclm-core",
3
- "version": "1.4.4",
3
+ "version": "1.4.5",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "",
@@ -6,43 +6,50 @@ import { pathToSlideZip } from '../lib/utils.js';
6
6
 
7
7
  export interface AdditionalField {
8
8
  header: string;
9
- value?: string;
9
+ value?: any;
10
10
  property?: string;
11
11
  }
12
12
 
13
+ export interface AdditionalFields {
14
+ presentation?: AdditionalField[];
15
+ slides?: AdditionalField[];
16
+ shared?: AdditionalField[];
17
+ }
18
+
13
19
  interface Params {
14
20
  config: IVeevaConfig
15
21
  deployDir: string;
16
22
  buildName: string;
17
23
  fieldsOnly?: boolean;
18
- additional?: {
19
- presentation: AdditionalField[];
20
- slides: AdditionalField[];
21
- shared: AdditionalField[];
22
- }
24
+ additionalFields?: AdditionalFields;
23
25
  }
24
- export default async function({ config, deployDir, buildName, fieldsOnly = false, additional }: Params) {
26
+ export default async function({ config, deployDir, buildName, fieldsOnly = false, additionalFields }: Params) {
25
27
  logger.info('Creating multichannel loader CSV');
26
- const headers: string[] = fieldsOnly ? CSV_HEADERS_FIELDS_ONLY : CSV_HEADERS;
28
+ const headers: string[] = [...(fieldsOnly ? CSV_HEADERS_FIELDS_ONLY : CSV_HEADERS)];
29
+
30
+ const additional = filterAdditionalFields(config, additionalFields);
31
+
27
32
  additional?.presentation?.forEach((a) => {
28
- if (a.value || (a.property && config.presentation[a.property as keyof typeof config.presentation])) {
33
+ if (!headers.includes(a.header) && (a.value || (a.property && (config.presentation as any)[a.property] !== undefined))) {
29
34
  headers.push(a.header);
30
35
  }
31
36
  });
32
37
  additional?.slides?.forEach((a) => {
33
- if (a.value) {
34
- headers.push(a.header);
35
- } else if (a.property && config.presentation.slides) {
36
- const slide = config.presentation.slides.find((s) => {
37
- return s[a.property as keyof typeof s]
38
- });
39
- if (slide) {
38
+ if (!headers.includes(a.header)) {
39
+ if (a.value) {
40
40
  headers.push(a.header);
41
+ } else if (a.property && config.presentation.slides) {
42
+ const slide = config.presentation.slides.find((s) => {
43
+ return s[a.property as keyof typeof s] !== undefined;
44
+ });
45
+ if (slide) {
46
+ headers.push(a.header);
47
+ }
41
48
  }
42
49
  }
43
50
  });
44
51
  additional?.shared?.forEach((a) => {
45
- if (a.value || (a.property && config.presentation.shared && config.presentation.shared[a.property as keyof typeof config.presentation.shared])) {
52
+ if (!headers.includes(a.header) && (a.value || (a.property && config.presentation.shared && (config.presentation.shared as any)[a.property] !== undefined))) {
46
53
  headers.push(a.header);
47
54
  }
48
55
  });
@@ -70,6 +77,23 @@ export default async function({ config, deployDir, buildName, fieldsOnly = false
70
77
  await writeFile(join(deployDir, `_${config.presentation.presentationId}_${buildName}.csv`), rows.map((r)=>{return r.join(',');}).join('\n'), { encoding: 'utf8' });
71
78
  }
72
79
 
80
+ function filterAdditionalFields(config: IVeevaConfig, additionalFields?: AdditionalFields): AdditionalFields | undefined {
81
+ if (!additionalFields) return undefined;
82
+
83
+ const additional: AdditionalFields = {};
84
+ additional.presentation = additionalFields?.presentation?.filter((v, i, a) => {
85
+ return a.findIndex(x => x.header === v.header) === i && (v.value !== undefined || v.property !== undefined);
86
+ });
87
+ additional.slides = additionalFields?.slides?.filter((v, i, a) => {
88
+ return a.findIndex(x => x.header === v.header) === i && (v.value !== undefined || v.property !== undefined);
89
+ });
90
+ additional.shared = additionalFields?.shared?.filter((v, i, a) => {
91
+ return a.findIndex(x => x.header === v.header) === i && (v.value !== undefined || v.property !== undefined);
92
+ });
93
+
94
+ return additional;
95
+ }
96
+
73
97
 
74
98
  const
75
99
  VEEVA_YES = 'YES',
@@ -200,7 +224,7 @@ function createPresentationRow(headers: string[], config: IVeevaConfig, addition
200
224
  addColumn(headers, row, header, presentation[key as keyof IVeevaClmBinderFields]);
201
225
  }
202
226
  additional?.forEach((a) => {
203
- addColumn(headers, row, a.header, a.property ? presentation[a.property as keyof typeof presentation] : a.value)
227
+ addColumn(headers, row, a.header, a.value ?? (presentation as any)[a.property as string]);
204
228
  });
205
229
  return row;
206
230
  }
@@ -241,7 +265,7 @@ function createSlideRow(headers: string[], config: IVeevaConfig, slide: IVeevaCo
241
265
  addColumn(headers, row, header, slide[key as keyof IVeevaClmBinderFields] ?? config.presentation.slideSettings?.[key as keyof IVeevaClmBinderFields] ?? config.slideSettings?.[key as keyof IVeevaClmBinderFields]);
242
266
  }
243
267
  additional?.forEach((a) => {
244
- addColumn(headers, row, a.header, a.property ? slide[a.property as keyof typeof slide] : a.value)
268
+ addColumn(headers, row, a.header, a.value ?? (slide as any)[a.property as string]);
245
269
  });
246
270
  return row;
247
271
  }
@@ -269,7 +293,7 @@ function createSharedRow(headers: string[], config: IVeevaConfig, additional?: A
269
293
  addColumn(headers, row, header, shared[key as keyof IVeevaClmBinderFields] ?? config.presentation.slideSettings?.[key as keyof IVeevaClmBinderFields] ?? config.slideSettings?.[key as keyof IVeevaClmBinderFields]);
270
294
  }
271
295
  additional?.forEach((a) => {
272
- addColumn(headers, row, a.header, a.property ? shared[a.property as keyof typeof shared] : a.value)
296
+ addColumn(headers, row, a.header, a.value ?? (shared as any)[a.property as string]);
273
297
  });
274
298
  return row;
275
299
  }
@@ -12,7 +12,7 @@ import copyFiles from './copy-files.js';
12
12
  import generateThumbs from './generate-thumbs.js';
13
13
  import updateShared from './update-shared.js';
14
14
  import createZips from './create-zips.js';
15
- import createCsv from './create-csv.js';
15
+ import createCsv, { type AdditionalFields } from './create-csv.js';
16
16
 
17
17
  const argv = parseArgv({
18
18
  mode: 'string',
@@ -27,8 +27,9 @@ interface Opts {
27
27
  env: string;
28
28
  csvOnly?: boolean;
29
29
  serverPort?: number;
30
+ additionalCsvFields?: AdditionalFields;
30
31
  }
31
- export default async function({ root, config, env, csvOnly = false, serverPort = 4320 }: Opts) {
32
+ export default async function({ root, config, env, csvOnly = false, serverPort = 4320, additionalCsvFields }: Opts) {
32
33
  const rootDir = root ?? process.cwd();
33
34
  // we could import the astro config and see if the outDir was set but right now it's not necessary
34
35
  const astroConfig = await getAstroConfig(root);
@@ -70,7 +71,7 @@ export default async function({ root, config, env, csvOnly = false, serverPort =
70
71
  await createZips({ config, deployDir });
71
72
  }
72
73
 
73
- await createCsv({ config, deployDir, buildName, fieldsOnly: csvOnly })
74
+ await createCsv({ config, deployDir, buildName, fieldsOnly: csvOnly, additionalFields: additionalCsvFields })
74
75
  }
75
76
 
76
77