@softwear/latestcollectioncore 1.0.187 → 1.0.189
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/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/projectObject.d.ts +5 -0
- package/dist/projectObject.js +23 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/projectObject.ts +16 -0
- package/src/reports.ts +11 -7
- package/test/projectObject.spec.js +25 -0
- package/test/reports.spec.ts +58 -0
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ 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 projectObject } from './projectObject';
|
|
17
18
|
export { default as reports, genPDF } from './reports';
|
|
18
19
|
export { default as round2 } from './round2';
|
|
19
20
|
export { default as sizeToMap } from './sizeToMap';
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.isAxiosError = exports.exponentialDelay = exports.axiosRetry = exports.createAxiosInstance = exports.lcAxios = exports.transaction = exports.sizeToMap = exports.round2 = exports.genPDF = exports.reports = exports.pivotTable = exports.isean13 = exports.imageBinder = exports.hasOnlyDigits = exports.hashBrand = exports.getPreferedPropertyMappings = exports.getBrandName = exports.findMetaBrandSetting = exports.findSkuByBarcode = exports.ensureImpliedProperties = exports.ensureArray = exports.edifact = exports.ean13 = exports.deepCopy = exports.buildPropertyMappingFn = exports.articleStatus = void 0;
|
|
20
|
+
exports.isAxiosError = exports.exponentialDelay = exports.axiosRetry = exports.createAxiosInstance = exports.lcAxios = exports.transaction = exports.sizeToMap = exports.round2 = exports.genPDF = exports.reports = exports.projectObject = exports.pivotTable = exports.isean13 = exports.imageBinder = exports.hasOnlyDigits = exports.hashBrand = exports.getPreferedPropertyMappings = exports.getBrandName = exports.findMetaBrandSetting = exports.findSkuByBarcode = exports.ensureImpliedProperties = exports.ensureArray = exports.edifact = exports.ean13 = exports.deepCopy = exports.buildPropertyMappingFn = exports.articleStatus = void 0;
|
|
21
21
|
var articleStatus_1 = require("./articleStatus");
|
|
22
22
|
Object.defineProperty(exports, "articleStatus", { enumerable: true, get: function () { return __importDefault(articleStatus_1).default; } });
|
|
23
23
|
var buildPropertyMappingFn_1 = require("./buildPropertyMappingFn");
|
|
@@ -50,6 +50,8 @@ var isean13_1 = require("./isean13");
|
|
|
50
50
|
Object.defineProperty(exports, "isean13", { enumerable: true, get: function () { return __importDefault(isean13_1).default; } });
|
|
51
51
|
var pivotTable_1 = require("./pivotTable");
|
|
52
52
|
Object.defineProperty(exports, "pivotTable", { enumerable: true, get: function () { return __importDefault(pivotTable_1).default; } });
|
|
53
|
+
var projectObject_1 = require("./projectObject");
|
|
54
|
+
Object.defineProperty(exports, "projectObject", { enumerable: true, get: function () { return __importDefault(projectObject_1).default; } });
|
|
53
55
|
var reports_1 = require("./reports");
|
|
54
56
|
Object.defineProperty(exports, "reports", { enumerable: true, get: function () { return __importDefault(reports_1).default; } });
|
|
55
57
|
Object.defineProperty(exports, "genPDF", { enumerable: true, get: function () { return reports_1.genPDF; } });
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whitelist projection: builds a new object from a deep-cloned copy of `source`,
|
|
3
|
+
* copying only the listed property names (nested values are cloned with `source`).
|
|
4
|
+
*/
|
|
5
|
+
export default function projectObject<K extends string>(source: unknown, keys: readonly K[]): Record<K, unknown>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const deepCopy_1 = __importDefault(require("./deepCopy"));
|
|
7
|
+
/**
|
|
8
|
+
* Whitelist projection: builds a new object from a deep-cloned copy of `source`,
|
|
9
|
+
* copying only the listed property names (nested values are cloned with `source`).
|
|
10
|
+
*/
|
|
11
|
+
function projectObject(source, keys) {
|
|
12
|
+
const out = {};
|
|
13
|
+
if (source == null)
|
|
14
|
+
return out;
|
|
15
|
+
if (typeof source !== 'object')
|
|
16
|
+
return out;
|
|
17
|
+
const tmp = (0, deepCopy_1.default)(source);
|
|
18
|
+
for (const k of keys) {
|
|
19
|
+
out[k] = tmp[k];
|
|
20
|
+
}
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
exports.default = projectObject;
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ 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 projectObject } from './projectObject'
|
|
17
18
|
export { default as reports, genPDF } from './reports'
|
|
18
19
|
export { default as round2 } from './round2'
|
|
19
20
|
export { default as sizeToMap } from './sizeToMap'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import deepCopy from './deepCopy'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Whitelist projection: builds a new object from a deep-cloned copy of `source`,
|
|
5
|
+
* copying only the listed property names (nested values are cloned with `source`).
|
|
6
|
+
*/
|
|
7
|
+
export default function projectObject<K extends string>(source: unknown, keys: readonly K[]): Record<K, unknown> {
|
|
8
|
+
const out = {} as Record<K, unknown>
|
|
9
|
+
if (source == null) return out
|
|
10
|
+
if (typeof source !== 'object') return out
|
|
11
|
+
const tmp = deepCopy(source) as Record<string, unknown>
|
|
12
|
+
for (const k of keys) {
|
|
13
|
+
out[k] = tmp[k]
|
|
14
|
+
}
|
|
15
|
+
return out
|
|
16
|
+
}
|
package/src/reports.ts
CHANGED
|
@@ -32,6 +32,12 @@ export interface PdfImageAsset {
|
|
|
32
32
|
export interface GenPdfOptions {
|
|
33
33
|
onAlert?: (alert: GenPdfAlert) => void
|
|
34
34
|
translate?: (key: string) => string
|
|
35
|
+
/**
|
|
36
|
+
* Called for layout fields with `format: 'currency'`. Receives the raw string from `source` (e.g. `"123.45"`).
|
|
37
|
+
* Return the exact string to draw. Callers normally pass a closure created next to `genPDF` so it can read
|
|
38
|
+
* `printBuffer`, tenant currency, locale, etc. If omitted, defaults to a euro prefix plus two decimals (`€ 123.45`).
|
|
39
|
+
*/
|
|
40
|
+
formatCurrency?: (rawAmountString: string) => string
|
|
35
41
|
resolveLogoUrl?: () => string | undefined
|
|
36
42
|
isCustomPdfFont?: (fontFamily: string) => boolean
|
|
37
43
|
getPdfFontDefinition?: (fontFamily: string) => PdfFontDefinition | undefined
|
|
@@ -353,7 +359,10 @@ function drawSimpleObject(x: number, y: number, doc: jsPDF, object: LayoutObject
|
|
|
353
359
|
options.onAlert?.({ header: 'fieldnotfound', body: object.source, type: 'warning', timeout: 10000 })
|
|
354
360
|
text = ''
|
|
355
361
|
}
|
|
356
|
-
if (object.format == 'currency')
|
|
362
|
+
if (object.format == 'currency') {
|
|
363
|
+
const raw = text
|
|
364
|
+
text = options.formatCurrency ? options.formatCurrency(raw) : '€ ' + parseFloat(raw).toFixed(2)
|
|
365
|
+
}
|
|
357
366
|
}
|
|
358
367
|
// Manipulate case as specified in object
|
|
359
368
|
if ((object.type === 'text' || object.type === 'field') && object.case === 1) text = text.toUpperCase()
|
|
@@ -586,12 +595,7 @@ addObjectToPDF = function (
|
|
|
586
595
|
const layoutYtenths = originY + object.y
|
|
587
596
|
const rawPrintOnlyAtStartOffset = printOnlyAtStartContainersOffset ?? 0
|
|
588
597
|
/** Must consult current page on every read: `addPage` can move to page 2+ mid-invocation while this call stays open. */
|
|
589
|
-
const effectivePrintOnlyAtStartContainersOffsetNow = (): number =>
|
|
590
|
-
containerChain.length === 0 &&
|
|
591
|
-
rawPrintOnlyAtStartOffset > 0 &&
|
|
592
|
-
getCurrentPageNumber(doc, context) === 1
|
|
593
|
-
? rawPrintOnlyAtStartOffset
|
|
594
|
-
: 0
|
|
598
|
+
const effectivePrintOnlyAtStartContainersOffsetNow = (): number => (containerChain.length === 0 && rawPrintOnlyAtStartOffset > 0 && getCurrentPageNumber(doc, context) === 1 ? rawPrintOnlyAtStartOffset : 0)
|
|
595
599
|
|
|
596
600
|
const x = layoutXtenths / 10
|
|
597
601
|
const y = (layoutYtenths + effectivePrintOnlyAtStartContainersOffsetNow()) / 10
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const { deepCopy, projectObject } = require('../dist/index')
|
|
2
|
+
|
|
3
|
+
describe('projectObject', function () {
|
|
4
|
+
it('returns an empty object for null/undefined', function () {
|
|
5
|
+
expect(projectObject(null, ['a'])).toEqual({})
|
|
6
|
+
expect(projectObject(undefined, ['a'])).toEqual({})
|
|
7
|
+
})
|
|
8
|
+
it('returns an empty object for non-object primitives', function () {
|
|
9
|
+
expect(projectObject('x', ['a'])).toEqual({})
|
|
10
|
+
expect(projectObject(1, ['a'])).toEqual({})
|
|
11
|
+
})
|
|
12
|
+
it('copies only listed keys from a deep-cloned source', function () {
|
|
13
|
+
const src = { id: '1', name: 'n', extra: 'drop', nest: { x: 1 } }
|
|
14
|
+
const p = projectObject(src, ['id', 'nest'])
|
|
15
|
+
expect(p).toEqual({ id: '1', nest: { x: 1 } })
|
|
16
|
+
expect(p.nest).not.toBe(src.nest)
|
|
17
|
+
expect(deepCopy(src.nest)).toEqual(p.nest)
|
|
18
|
+
})
|
|
19
|
+
it('does not mutate the original when copying nested data', function () {
|
|
20
|
+
const src = { a: { b: 1 } }
|
|
21
|
+
const p = projectObject(src, ['a'])
|
|
22
|
+
p.a.b = 2
|
|
23
|
+
expect(src.a.b).toBe(1)
|
|
24
|
+
})
|
|
25
|
+
})
|
package/test/reports.spec.ts
CHANGED
|
@@ -331,4 +331,62 @@ describe('genPDF', () => {
|
|
|
331
331
|
expect(chromeMatches?.length ?? 0).toBeGreaterThanOrEqual(doc.getNumberOfPages())
|
|
332
332
|
expect(pdfText).toContain('SKU_20')
|
|
333
333
|
})
|
|
334
|
+
|
|
335
|
+
it('uses GenPdfOptions.formatCurrency for currency fields when provided', async () => {
|
|
336
|
+
const layout: Layout = {
|
|
337
|
+
name: 'currency-inject',
|
|
338
|
+
paperSize: { width: 210, height: 297, footerHeight: 20 },
|
|
339
|
+
objects: [
|
|
340
|
+
{
|
|
341
|
+
type: 'field' as const,
|
|
342
|
+
name: 'amount',
|
|
343
|
+
x: 20,
|
|
344
|
+
y: 20,
|
|
345
|
+
width: 500,
|
|
346
|
+
height: 50,
|
|
347
|
+
active: true,
|
|
348
|
+
source: 'amount',
|
|
349
|
+
format: 'currency' as const,
|
|
350
|
+
textAlign: 1 as const,
|
|
351
|
+
fontFamily: 'Helvetica',
|
|
352
|
+
fontSize: 32,
|
|
353
|
+
fontStyle: 0,
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
}
|
|
357
|
+
const printBuffer = { amount: '99.5', currency: 'USD' }
|
|
358
|
+
const doc = await genPDF(layout, printBuffer, {
|
|
359
|
+
formatCurrency: (raw) => `USD ${raw} BUF:${printBuffer.currency}`,
|
|
360
|
+
})
|
|
361
|
+
const pdfText = Buffer.from(doc.output('arraybuffer')).toString('latin1')
|
|
362
|
+
expect(pdfText).toContain('USD 99.5 BUF:USD')
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
it('defaults currency fields to euro-style prefix when formatCurrency is omitted', async () => {
|
|
366
|
+
const layout: Layout = {
|
|
367
|
+
name: 'currency-default',
|
|
368
|
+
paperSize: { width: 210, height: 297, footerHeight: 20 },
|
|
369
|
+
objects: [
|
|
370
|
+
{
|
|
371
|
+
type: 'field' as const,
|
|
372
|
+
name: 'amount',
|
|
373
|
+
x: 20,
|
|
374
|
+
y: 20,
|
|
375
|
+
width: 500,
|
|
376
|
+
height: 50,
|
|
377
|
+
active: true,
|
|
378
|
+
source: 'amount',
|
|
379
|
+
format: 'currency' as const,
|
|
380
|
+
textAlign: 1 as const,
|
|
381
|
+
fontFamily: 'Helvetica',
|
|
382
|
+
fontSize: 32,
|
|
383
|
+
fontStyle: 0,
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
}
|
|
387
|
+
const doc = await genPDF(layout, { amount: '10' })
|
|
388
|
+
const pdfText = Buffer.from(doc.output('arraybuffer')).toString('latin1')
|
|
389
|
+
// jsPDF encodes U+20AC as WinAnsi 0x80 in the text operator; still one glyph before digits.
|
|
390
|
+
expect(pdfText).toMatch(/\(\s*.\s*10\.00\) Tj/)
|
|
391
|
+
})
|
|
334
392
|
})
|