@softwear/latestcollectioncore 1.0.174 → 1.0.176

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softwear/latestcollectioncore",
3
- "version": "1.0.174",
3
+ "version": "1.0.176",
4
4
  "description": "Core functions for LatestCollections applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -37,6 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "date-fns": "^2.29.3",
40
- "filtrex": "^2.2.3"
40
+ "filtrex": "^2.2.3",
41
+ "jspdf": "^4.2.1"
41
42
  }
42
43
  }
@@ -32,18 +32,19 @@ function prepFilterSkusImages(filteredSkus: SkuI[], merge = true, fileNames: Arr
32
32
  const skusCopy = deepCopy(filteredSkus)
33
33
  const preppedSkus: Array<Record<string, any>> = []
34
34
  const fileNames2skip: Array<string> = []
35
- let idx = 0
36
- skusCopy.forEach((sku) => {
37
- const fieldsToBeMerged = {}
35
+ skusCopy.forEach((sku, idx) => {
38
36
  if (sku.images && sku.images.length > 0) {
39
37
  // If a fileName is already matched, we skip it
40
38
  fileNames.forEach((fileName) => {
41
- if (sku.images?.includes(fileName) && !fileNames2skip.includes(fileName)) fileNames2skip.push(fileName)
39
+ if (sku.images?.includes(fileName) && fileNames2skip.indexOf(fileName) == -1) fileNames2skip.push(fileName)
42
40
  })
43
41
  // If a sku has images, we skip it
42
+ sku['skip'] = true
43
+ preppedSkus.push(sku)
44
44
  return
45
45
  }
46
46
 
47
+ const fieldsToBeMerged = {}
47
48
  for (const fieldName in sku) {
48
49
  if (fieldName == '__created' || fieldName == '__modified' || fieldName == 'images' || fieldName == 'brandhash' || (merge == true && fieldName == 'colorFamily')) continue
49
50
  let fieldVal = sku[fieldName]
@@ -70,7 +71,6 @@ function prepFilterSkusImages(filteredSkus: SkuI[], merge = true, fileNames: Arr
70
71
  } else {
71
72
  const newSku = {}
72
73
  newSku['originalSku'] = filteredSkus[idx]
73
- idx++
74
74
  for (const fieldVal in fieldsToBeMerged) {
75
75
  const fieldNameArray = fieldsToBeMerged[fieldVal].sort()
76
76
  if (fieldNameArray.length > 1) {
@@ -83,7 +83,7 @@ function prepFilterSkusImages(filteredSkus: SkuI[], merge = true, fileNames: Arr
83
83
  }
84
84
  })
85
85
  const fileNames2Match = fileNames.filter((fileName) => {
86
- return fileNames2skip.includes(fileName) == false
86
+ return fileNames2skip.indexOf(fileName) == -1
87
87
  })
88
88
  return { preppedSkus: preppedSkus, fileNames2Match: fileNames2Match }
89
89
  }
@@ -116,7 +116,7 @@ function checkWithoutLast(fileName: string) {
116
116
  .toLowerCase()
117
117
  .split(/[_\-.\s()]+|%[0-9A-Fa-f]{2}/)
118
118
  .slice(0, -1)
119
- const lastToken = tokens.at(-1)
119
+ const lastToken = tokens[tokens.length - 1]
120
120
  let returnWithoutLast = false
121
121
  if (lastToken) {
122
122
  if (lastToken.includes('front') || lastToken.includes('back') || lastToken.includes('side') || lastToken.includes('sole')) returnWithoutLast = true
@@ -167,7 +167,7 @@ function testQuickSearch(
167
167
  if (pair[0] == cleanedFileName) {
168
168
  indicesToReturn.push(idx)
169
169
  patternStringFound = quickSearchPattern
170
- } else if (indicesToReturn.length == 0 && pair[0] == fileNameWithoutLast && !indicesWithoutLast.includes(idx)) {
170
+ } else if (indicesToReturn.length == 0 && pair[0] == fileNameWithoutLast && indicesWithoutLast.indexOf(idx) == -1) {
171
171
  indicesWithoutLast.push(idx)
172
172
  patternStringFound = quickSearchPattern
173
173
  }
@@ -188,6 +188,7 @@ function prepQuickSearch(preppedSkus: any): Record<string, Array<any>> {
188
188
  patternStrings.push(pattern.join('-'))
189
189
  })
190
190
  preppedSkus.forEach((sku, idx) => {
191
+ if (sku['skip']) return
191
192
  GLOBAL_PATTERNS.forEach((pattern, patternIndex) => {
192
193
  const proposedFilename = pattern.reduce((out, field) => out + (field in sku ? sku[field] : ''), '')
193
194
  if (proposedFilename) {
@@ -204,11 +205,10 @@ function prepQuickSearch(preppedSkus: any): Record<string, Array<any>> {
204
205
 
205
206
  function addNewPatternToQuickSearch(preppedSkus: any, pattern: Array<string>, quickSearch: Record<string, Array<Array<any>>>): Record<string, Array<any>> {
206
207
  const newQuickSearchArray: Array<Array<any>> = []
207
- let idx = 0
208
- preppedSkus.forEach((sku) => {
208
+ preppedSkus.forEach((sku, idx) => {
209
+ if (sku['skip']) return
209
210
  const proposedFilename = pattern.reduce((out, field) => out + (field in sku ? sku[field] : ''), '')
210
211
  if (proposedFilename) newQuickSearchArray.push([proposedFilename, idx])
211
- idx++
212
212
  })
213
213
  quickSearch[pattern.join('-')] = newQuickSearchArray
214
214
  return quickSearch
@@ -223,6 +223,7 @@ function fallbackSearch(cleanedFileName: string, fileNameWithoutLast: string, pr
223
223
  let currentBestSubstringPatterns: Record<string, Array<number>> = {}
224
224
  let maxPatternlength = 0
225
225
  preppedSkus.forEach((sku, idx) => {
226
+ if (sku['skip']) return
226
227
  if (pattern_found.length > 0) {
227
228
  // In case a new pattern has been found in one sku, test that on the remaining skus. If they don't match the pattern, skip them.
228
229
  const proposedFilename = pattern_found.reduce((out, field) => out + (field in sku ? sku[field] : ''), '')
@@ -282,15 +283,15 @@ function fallbackSearch(cleanedFileName: string, fileNameWithoutLast: string, pr
282
283
  substringPattern.splice(idx, 1)
283
284
  }
284
285
  })
285
- const proposedFilename = Object.values(substringObject).join('')
286
+ const proposedFilename = (<any>Object).values(substringObject).join('')
286
287
  if (proposedFilename == cleanedFileName || (fileNameWithoutLast && proposedFilename == fileNameWithoutLast)) {
287
288
  // We've discovered a new pattern
288
- pattern_found = Object.values(patternObject)
289
+ pattern_found = (<any>Object).values(patternObject)
289
290
  exactMatches.push(idx)
290
291
  return
291
292
  }
292
- patternString = Object.values(patternObject).join('-')
293
- const revisedPatternLength = Object.values(patternObject).length
293
+ patternString = (<any>Object).values(patternObject).join('-')
294
+ const revisedPatternLength = (<any>Object).values(patternObject).length
294
295
  if (revisedPatternLength == maxPatternlength) {
295
296
  // We've found a new pattern of the same length, so we keep this one too
296
297
  if (patternString in currentBestSubstringPatterns) {
@@ -317,7 +318,7 @@ function fallbackSearch(cleanedFileName: string, fileNameWithoutLast: string, pr
317
318
  const sku = preppedSkus[idx]
318
319
  pattern.forEach((fieldName) => {
319
320
  const fieldVal = sku[fieldName]
320
- if (fieldVal && !uniqueFieldVals.includes(fieldVal)) uniqueFieldVals.push(fieldVal)
321
+ if (fieldVal && uniqueFieldVals.indexOf(fieldVal) == -1) uniqueFieldVals.push(fieldVal)
321
322
  })
322
323
  })
323
324
  uniqueFieldVals.sort((a, b) => {
@@ -364,6 +365,7 @@ function imageBinder(fileNames: Array<string>, filteredSkus: SkuI[], brand: stri
364
365
  const fileNameWithoutLast = checkWithoutLast(fileName)
365
366
  fileNameIndexMatch[fileName] = []
366
367
  preppedSkus.forEach((sku, idx) => {
368
+ if (sku['skip']) return
367
369
  let skuStillMatches = true
368
370
  specifiedPattern.every((fieldName) => {
369
371
  if (!(fieldName in sku)) skuStillMatches = false
package/src/index.ts CHANGED
@@ -14,9 +14,12 @@ export { default as hasOnlyDigits } from './hasOnlyDigits'
14
14
  export { default as imageBinder } from './imageBinder'
15
15
  export { default as isean13 } from './isean13'
16
16
  export { default as pivotTable } from './pivotTable'
17
+ export { default as reports, genPDF } from './reports'
17
18
  export { default as round2 } from './round2'
18
19
  export { default as sizeToMap } from './sizeToMap'
19
20
  export { default as transaction } from './transaction'
21
+ export * from './pdf'
22
+ export type { GenPdfAlert, GenPdfOptions, PdfFontDefinition, PdfFontVariant, PdfImageAsset } from './reports'
20
23
  export * from './types'
21
24
  export * from './consts'
22
25
  export {
package/src/pdf.ts ADDED
@@ -0,0 +1,76 @@
1
+ export interface PaperSize {
2
+ width: number
3
+ height: number
4
+ footerHeight: number
5
+ }
6
+
7
+ export type TextAlign = 1 | 2 | 3 // 1: left, 2: center, 3: right
8
+ export type ObjectType = 'text' | 'field' | 'rectangle' | 'image' | 'container'
9
+ export type RepeatContainer = 'horizontal' | 'vertical' | undefined
10
+
11
+ export interface BaseLayoutObject {
12
+ type: ObjectType
13
+ x: number
14
+ y: number
15
+ width: number
16
+ height: number
17
+ active?: boolean
18
+ snapToBottom?: boolean
19
+ name?: string
20
+ }
21
+
22
+ export interface TextLayoutObject extends BaseLayoutObject {
23
+ type: 'text'
24
+ text: string
25
+ textAlign?: TextAlign
26
+ fontFamily: string
27
+ fontSize: number
28
+ fontStyle: number
29
+ case?: 1 | 2 // 1: uppercase, 2: lowercase
30
+ }
31
+
32
+ export interface FieldLayoutObject extends BaseLayoutObject {
33
+ type: 'field'
34
+ source?: string
35
+ format?: 'date' | 'currency'
36
+ textAlign?: TextAlign
37
+ fontFamily: string
38
+ fontSize: number
39
+ fontStyle: number
40
+ case?: 1 | 2
41
+ }
42
+
43
+ export interface RectangleLayoutObject extends BaseLayoutObject {
44
+ type: 'rectangle'
45
+ }
46
+
47
+ export interface ImageLayoutObject extends BaseLayoutObject {
48
+ type: 'image'
49
+ url?: string
50
+ image?: HTMLImageElement
51
+ }
52
+
53
+ export interface ContainerLayoutObject extends BaseLayoutObject {
54
+ type: 'container'
55
+ source: string
56
+ children: LayoutObject[]
57
+ repeatContainer?: RepeatContainer
58
+ repeatOnOverflow?: boolean
59
+ pageBreak?: boolean
60
+ /** Minimum mm of remaining space before drawing next item; if less, break to next page first */
61
+ minHeightBeforeBreak?: number
62
+ /** When true, container and children are drawn only once at the end of the report, not on every page */
63
+ printOnlyAtEnd?: boolean
64
+ }
65
+
66
+ export type LayoutObject = TextLayoutObject | FieldLayoutObject | RectangleLayoutObject | ImageLayoutObject | ContainerLayoutObject
67
+
68
+ export interface Layout {
69
+ name?: string
70
+ group?: string
71
+ paperSize: PaperSize
72
+ objects: LayoutObject[]
73
+ active?: boolean
74
+ /** Default font for text/field objects that have no fontFamily. E.g. 'Inter', 'Helvetica'. */
75
+ defaultFontFamily?: string
76
+ }