UNPKG

xero-hero

Version:

Heroic utilities to simplify and enable your progress with the [xero-node](https://www.npmjs.com/package/xero-node) SDK.

1 lines 10.9 kB
{"version":3,"sources":["../../../../src/accounting/attachments/__tests__/requests.test.ts","../../../../node_modules/uuid/dist/esm-node/rng.js","../../../../node_modules/uuid/dist/esm-node/stringify.js","../../../../node_modules/uuid/dist/esm-node/native.js","../../../../node_modules/uuid/dist/esm-node/v4.js","../../../../src/common/instance/operations.ts","../../../../src/accounting/attachments/requests.ts","../../../../src/accounting/contacts/links.ts","../../../../src/accounting/invoices/lineItems.ts","../../../../src/accounting/journals/links.ts","../../../../src/projects/timeEntries.ts"],"sourcesContent":["import { Duplex } from 'node:stream';\r\n\r\nimport { v4 as uuid } from 'uuid';\r\nimport type { XeroClient } from 'xero-node';\r\n\r\nimport { createInvoiceAttachment } from '../../../';\r\n\r\nconst getMockXeroClient = (): any => {\r\n return {\r\n accountingApi: {\r\n createInvoiceAttachmentByFileName: jest.fn(),\r\n },\r\n };\r\n};\r\n\r\ndescribe('attachments/requests', () => {\r\n describe('createInvoiceAttachment()', () => {\r\n it('should call the createInvoiceAttachmentByFileName() method with the relevant arguments ', () => {\r\n const client = getMockXeroClient() as unknown as XeroClient;\r\n const tenantId = uuid();\r\n const invoiceId = uuid();\r\n const filename = 'test.pdf';\r\n const contents = Buffer.from('Test Content Here');\r\n\r\n createInvoiceAttachment(client, tenantId, {\r\n contents,\r\n filename,\r\n invoiceId,\r\n });\r\n\r\n expect(\r\n client.accountingApi.createInvoiceAttachmentByFileName,\r\n ).toHaveBeenCalledWith(tenantId, invoiceId, filename, expect.any(Duplex));\r\n });\r\n });\r\n});\r\n","import crypto from 'crypto';\nconst rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate\n\nlet poolPtr = rnds8Pool.length;\nexport default function rng() {\n if (poolPtr > rnds8Pool.length - 16) {\n crypto.randomFillSync(rnds8Pool);\n poolPtr = 0;\n }\n\n return rnds8Pool.slice(poolPtr, poolPtr += 16);\n}","import validate from './validate.js';\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\n\nconst byteToHex = [];\n\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\n\nexport function unsafeStringify(arr, offset = 0) {\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];\n}\n\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n\n return uuid;\n}\n\nexport default stringify;","import crypto from 'crypto';\nexport default {\n randomUUID: crypto.randomUUID\n};","import native from './native.js';\nimport rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\n\nfunction v4(options, buf, offset) {\n if (native.randomUUID && !buf && !options) {\n return native.randomUUID();\n }\n\n options = options || {};\n const rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided\n\n if (buf) {\n offset = offset || 0;\n\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n\n return buf;\n }\n\n return unsafeStringify(rnds);\n}\n\nexport default v4;","import { isObject } from 'deep-cuts';\r\n\r\nexport const deepClone = <T extends object>(instance: T): T => {\r\n if (instance && isObject(instance)) {\r\n const { constructor } = instance;\r\n // @ts-expect-error - This is not passing for TypeScript, bit will for any Xero class.\r\n const clone = new constructor();\r\n /* eslint-disable guard-for-in, functional/immutable-data */\r\n for (const key in instance) {\r\n clone[key] = deepClone(instance[key] as object);\r\n }\r\n /* eslint-enable guard-for-in, functional/immutable-data */\r\n\r\n return clone;\r\n }\r\n\r\n return instance;\r\n};\r\n","import type { ReadStream } from 'node:fs';\r\nimport type http from 'node:http';\r\n\r\nimport { bufferToStream } from 'tranquil-stream';\r\nimport type { Attachments, XeroClient } from 'xero-node';\r\n\r\ntype ICreateInvoiceAttachmentParameters = {\r\n contents: Buffer;\r\n filename: string;\r\n invoiceId: string;\r\n};\r\n\r\nexport const createInvoiceAttachment = async (\r\n client: XeroClient,\r\n tenantId: string,\r\n { invoiceId, filename, contents }: ICreateInvoiceAttachmentParameters,\r\n): Promise<{\r\n body: Attachments;\r\n response: http.IncomingMessage;\r\n}> => {\r\n return client.accountingApi.createInvoiceAttachmentByFileName(\r\n tenantId,\r\n invoiceId,\r\n filename,\r\n bufferToStream(contents) as unknown as ReadStream,\r\n );\r\n};\r\n","import qs from 'qs';\r\nimport type { Contact } from 'xero-node';\r\n\r\nimport { hasProperty } from '../../utils/properties';\r\n\r\nexport const getContactLink = (contact: Contact | string): string => {\r\n return `https://go.xero.com/Contacts/View.aspx?${qs.stringify({\r\n contactID:\r\n (hasProperty(contact, 'contactID')\r\n ? (contact as Contact).contactID\r\n : contact) || 'null-or-empty-contact-id',\r\n })}`;\r\n};\r\n","import { isNil } from 'deep-cuts';\r\nimport type { LineItem } from 'xero-node';\r\n\r\nimport type { DecisionFunction } from '../../types';\r\n\r\nexport const filterInvoiceLineItems = (\r\n lineItems: LineItem[],\r\n minCode: DecisionFunction<LineItem> | string | number,\r\n maxCode?: string | number,\r\n): LineItem[] => {\r\n if (typeof minCode === 'function') {\r\n return (lineItems || []).filter(minCode);\r\n }\r\n\r\n const parsedMinCode = isNil(minCode)\r\n ? minCode\r\n : Number.parseInt(minCode as string, 10);\r\n const parsedMaxCode = isNil(maxCode)\r\n ? maxCode\r\n : Number.parseInt(maxCode as string, 10);\r\n if (parsedMinCode || parsedMaxCode) {\r\n return (lineItems || []).filter(({ itemCode }) => {\r\n const parsedItemCode = isNil(itemCode)\r\n ? itemCode\r\n : Number.parseInt(itemCode as string, 10);\r\n if (parsedItemCode) {\r\n const greaterThanOrEqualToMinCode = isNil(parsedMinCode)\r\n ? true\r\n : parsedItemCode >= parsedMinCode;\r\n const lessThanOrEqualToMaxCode = isNil(parsedMaxCode)\r\n ? true\r\n : parsedItemCode <= (parsedMaxCode || 0);\r\n return greaterThanOrEqualToMinCode && lessThanOrEqualToMaxCode;\r\n }\r\n\r\n return false;\r\n });\r\n }\r\n\r\n return lineItems || [];\r\n};\r\n","import qs from 'qs';\r\nimport type { ManualJournal } from 'xero-node';\r\n\r\nimport { hasProperty } from '../../utils/properties';\r\n\r\nexport const getManualJournalLink = (\r\n manualJournal: ManualJournal | string,\r\n): string => {\r\n return `https://go.xero.com/Journal/View.aspx?${qs.stringify({\r\n invoiceID:\r\n (hasProperty(manualJournal, 'manualJournalID')\r\n ? (manualJournal as ManualJournal).manualJournalID\r\n : manualJournal) || 'null-or-empty-manual-journal-id',\r\n })}`;\r\n};\r\n","import { roundToNearestFraction } from 'deep-cuts';\r\n\r\nimport type { TimeEntry } from './shimTypes';\r\n\r\nexport const hoursFromTimeEntries = (\r\n timeEntries: TimeEntry[],\r\n denominator: number = 4,\r\n maxDecimalPlaces: number = 2,\r\n): number | undefined => {\r\n const totalMinutes = timeEntries.reduce((totalMinutes, timeEntry) => {\r\n const duration = timeEntry.duration || 0;\r\n return totalMinutes + duration;\r\n }, 0);\r\n return roundToNearestFraction(\r\n totalMinutes / 60,\r\n denominator,\r\n maxDecimalPlaces,\r\n );\r\n};\r\n"],"mappings":"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","names":["crypto","qs"]}