piper-utils 1.1.71 → 1.1.72

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/nul ADDED
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.watchBucket = exports.userDefaultBid = exports.successHtml = exports.success = exports.stampOwnBusinessId = exports.scopeToPartnerBook = exports.scopeToOwnBusiness = exports.scopeToBookUnionOwn = exports.runMigrations = exports.resolveAccess = exports.requireTicketAccess = exports.requireSuper = exports.requireCrmAccess = exports.publishEvents = exports.parseEvent = exports.parseBody = exports.isSystemUser = exports.isSuperUser = exports.isPartnerUser = exports.isContractChoice = exports.incrementWithAudit = exports.handleFile = exports.getRequestedBusinessIds = exports.getPagination = exports.getModuleInfo = exports.getEffectivePartnerId = exports.getDefaultBusinessIDInfo = exports.getCurrentUserNameFromCognitoEvent = exports.getCurrentUser = exports.getCompanySettings = exports.getBusinessesInfo = exports.getBelongsToPartnerId = exports.getAuditModel = exports.getAuditFilter = exports.getAccessRightsInfo = exports.findAll = exports.failure = exports.ensurePartnerScope = exports.enrichEventWithPartnerAccess = exports.defaultFilters = exports.decrementWithAudit = exports.createSort = exports.createIncludes = exports.createFilters = exports.createAccessHelpers = exports.contractStatuses = exports.contractChoices = exports.checkWriteAccess = exports.checkModule = exports.checkIsSuper = exports.bindAuditRequestForUser = exports.bindAuditRequest = exports.attachAudit = exports.assertCanWriteOwnBusiness = exports.assertCanWriteBookUnionOwn = exports.assertCanWriteBookBusiness = exports.accessRightsUtils = void 0;
7
+ var _handleFile = require("./eventManager/handleFile.js");
8
+ var _watchBucket = require("./eventManager/watchBucket.js");
9
+ var _publishEvents = require("./eventManager/publishEvents.js");
10
+ var _createIncludes = require("./database/dbUtils/queryStringUtils/createIncludes.js");
11
+ var _createFilters = require("./database/dbUtils/queryStringUtils/createFilters.js");
12
+ var _createSort = require("./database/dbUtils/queryStringUtils/createSort.js");
13
+ var _findAll = require("./database/dbUtils/queryStringUtils/findAll.js");
14
+ var _accessRightsUtils = require("./database/dbUtils/queryStringUtils/accessRightsUtils.js");
15
+ var _requestResponse = require("./requestResponse/requestResponse.js");
16
+ var _migrations = require("./database/dbSetup/migrations.js");
17
+ var _defaultFilters = require("./database/dbUtils/queryStringUtils/defaultFilters.js");
18
+ var _getPagination = require("./database/dbUtils/queryStringUtils/getPagination.js");
19
+ var _accessContext = require("./database/dbUtils/partnerAccess/accessContext.js");
20
+ var _accessGates = require("./database/dbUtils/partnerAccess/accessGates.js");
21
+ var _accessScope = require("./database/dbUtils/partnerAccess/accessScope.js");
22
+ var _accessWrites = require("./database/dbUtils/partnerAccess/accessWrites.js");
23
+ var _createAccessHelpers = require("./database/dbUtils/partnerAccess/createAccessHelpers.js");
24
+ var _contract = require("./contract/contract.js");
25
+ var _audit = require("./audit/audit.js");
26
+ const handleFile = exports.handleFile = _handleFile.handleFile;
27
+ const watchBucket = exports.watchBucket = _watchBucket.watchBucket;
28
+ const publishEvents = exports.publishEvents = _publishEvents.publishEvents;
29
+ const createFilters = exports.createFilters = _createFilters.createFilters;
30
+ const createIncludes = exports.createIncludes = _createIncludes.createIncludes;
31
+ const createSort = exports.createSort = _createSort.createSort;
32
+ const findAll = exports.findAll = _findAll.findAll;
33
+ const getPagination = exports.getPagination = _getPagination.getPagination;
34
+ const getRequestedBusinessIds = exports.getRequestedBusinessIds = _accessRightsUtils.getRequestedBusinessIds;
35
+ const checkModule = exports.checkModule = _accessRightsUtils.checkModule;
36
+ const checkIsSuper = exports.checkIsSuper = _accessRightsUtils.checkIsSuper;
37
+ const getAccessRightsInfo = exports.getAccessRightsInfo = _accessRightsUtils.getAccessRightsInfo;
38
+ const getDefaultBusinessIDInfo = exports.getDefaultBusinessIDInfo = _accessRightsUtils.getDefaultBusinessIDInfo;
39
+ const getModuleInfo = exports.getModuleInfo = _accessRightsUtils.getModuleInfo;
40
+ const failure = exports.failure = _requestResponse.failure;
41
+ const success = exports.success = _requestResponse.success;
42
+ const runMigrations = exports.runMigrations = _migrations.runMigrations;
43
+ const getCurrentUser = exports.getCurrentUser = _requestResponse.getCurrentUser;
44
+ const successHtml = exports.successHtml = _requestResponse.successHtml;
45
+ const getCurrentUserNameFromCognitoEvent = exports.getCurrentUserNameFromCognitoEvent = _requestResponse.getCurrentUserNameFromCognitoEvent;
46
+ const defaultFilters = exports.defaultFilters = _defaultFilters.defaultFilters;
47
+ const accessRightsUtils = exports.accessRightsUtils = _accessRightsUtils.accessRightsUtils;
48
+ const parseBody = exports.parseBody = _requestResponse.parseBody;
49
+ const parseEvent = exports.parseEvent = _requestResponse.parseEvent;
50
+ const getBusinessesInfo = exports.getBusinessesInfo = _accessRightsUtils.getBusinessesInfo;
51
+ const userDefaultBid = exports.userDefaultBid = _accessRightsUtils.userDefaultBid;
52
+ const checkWriteAccess = exports.checkWriteAccess = _accessRightsUtils.checkWriteAccess;
53
+ const isSystemUser = exports.isSystemUser = _accessRightsUtils.isSystemUser;
54
+ const isSuperUser = exports.isSuperUser = _accessRightsUtils.isSuperUser;
55
+ const isPartnerUser = exports.isPartnerUser = _accessRightsUtils.isPartnerUser;
56
+ const getBelongsToPartnerId = exports.getBelongsToPartnerId = _accessRightsUtils.getBelongsToPartnerId;
57
+ const getEffectivePartnerId = exports.getEffectivePartnerId = _accessRightsUtils.getEffectivePartnerId;
58
+ const enrichEventWithPartnerAccess = exports.enrichEventWithPartnerAccess = _accessRightsUtils.enrichEventWithPartnerAccess;
59
+ const getCompanySettings = exports.getCompanySettings = _accessRightsUtils.getCompanySettings;
60
+ const resolveAccess = exports.resolveAccess = _accessContext.resolveAccess;
61
+ const ensurePartnerScope = exports.ensurePartnerScope = _accessContext.ensurePartnerScope;
62
+ const requireCrmAccess = exports.requireCrmAccess = _accessGates.requireCrmAccess;
63
+ const requireTicketAccess = exports.requireTicketAccess = _accessGates.requireTicketAccess;
64
+ const requireSuper = exports.requireSuper = _accessGates.requireSuper;
65
+ const scopeToOwnBusiness = exports.scopeToOwnBusiness = _accessScope.scopeToOwnBusiness;
66
+ const scopeToPartnerBook = exports.scopeToPartnerBook = _accessScope.scopeToPartnerBook;
67
+ const scopeToBookUnionOwn = exports.scopeToBookUnionOwn = _accessScope.scopeToBookUnionOwn;
68
+ const assertCanWriteOwnBusiness = exports.assertCanWriteOwnBusiness = _accessWrites.assertCanWriteOwnBusiness;
69
+ const assertCanWriteBookBusiness = exports.assertCanWriteBookBusiness = _accessWrites.assertCanWriteBookBusiness;
70
+ const assertCanWriteBookUnionOwn = exports.assertCanWriteBookUnionOwn = _accessWrites.assertCanWriteBookUnionOwn;
71
+ const stampOwnBusinessId = exports.stampOwnBusinessId = _accessWrites.stampOwnBusinessId;
72
+ const createAccessHelpers = exports.createAccessHelpers = _createAccessHelpers.createAccessHelpers;
73
+ const attachAudit = exports.attachAudit = _audit.attachAudit;
74
+ const bindAuditRequest = exports.bindAuditRequest = _audit.bindAuditRequest;
75
+ const bindAuditRequestForUser = exports.bindAuditRequestForUser = _audit.bindAuditRequestForUser;
76
+ const decrementWithAudit = exports.decrementWithAudit = _audit.decrementWithAudit;
77
+ const getAuditFilter = exports.getAuditFilter = _audit.getAuditFilter;
78
+ const getAuditModel = exports.getAuditModel = _audit.getAuditModel;
79
+ const incrementWithAudit = exports.incrementWithAudit = _audit.incrementWithAudit;
80
+ const contractChoices = exports.contractChoices = _contract.contractChoices;
81
+ const contractStatuses = exports.contractStatuses = _contract.contractStatuses;
82
+ const isContractChoice = exports.isContractChoice = _contract.isContractChoice;
package/package.json CHANGED
@@ -1,62 +1,62 @@
1
- {
2
- "name": "piper-utils",
3
- "version": "1.1.71",
4
- "description": "Utility library for Piper",
5
- "main": "bin/main.js",
6
- "scripts": {
7
- "test": "cross-env BUILD_ENV='test' nyc jasmine JASMINE_CONFIG_PATH=jasmine.json",
8
- "itest": "cross-env BUILD_ENV='development' nyc jasmine JASMINE_CONFIG_PATH=jasmine.json",
9
- "build": "webpack --config webpack.config.js",
10
- "build-prod": "cross-env BUILD_ENV='production' webpack --config webpack.config.js"
11
- },
12
- "repository": {
13
- "type": "git"
14
- },
15
- "author": "Kevin Batchelor",
16
- "license": "PVT",
17
- "devDependencies": {
18
- "@babel/cli": "7.11.6",
19
- "@babel/core": "7.23.2",
20
- "@babel/preset-env": "^7.29.0",
21
- "@babel/register": "^7.28.6",
22
- "@babel/runtime": "8.0.0-alpha.17",
23
- "aws-sdk-client-mock": "^3.0.1",
24
- "babel-loader": "9.1.3",
25
- "babel-preset-env": "1.7.0",
26
- "cross-env": "7.0.3",
27
- "jasmine": "5.1.0",
28
- "nyc": "14.1.1",
29
- "terser-webpack-plugin": "^5.3.10",
30
- "webpack": "5.104.1",
31
- "webpack-cli": "^5.1.4",
32
- "webpack-node-externals": "3.0.0"
33
- },
34
- "dependencies": {
35
- "@aws-sdk/client-dynamodb": "^3.507.0",
36
- "@aws-sdk/client-s3": "^3.507.0",
37
- "@aws-sdk/client-sns": "^3.507.0",
38
- "@aws-sdk/lib-dynamodb": "^3.507.0",
39
- "babel-runtime": "6.26.0"
40
- },
41
- "peerDependencies": {
42
- "bluebird": ">=3.7.0",
43
- "dayjs": "^1.11.13",
44
- "lodash": ">=4.17.15",
45
- "sequelize": ">=6.6.2",
46
- "umzug": ">=3.2.1"
47
- },
48
- "nyc": {
49
- "require": [
50
- "@babel/register"
51
- ],
52
- "reporter": [
53
- "lcov",
54
- "text-summary"
55
- ],
56
- "check-coverage": true,
57
- "branches": 70,
58
- "lines": 80,
59
- "functions": 70,
60
- "statements": 85
61
- }
62
- }
1
+ {
2
+ "name": "piper-utils",
3
+ "version": "1.1.72",
4
+ "description": "Utility library for Piper",
5
+ "main": "bin/main.js",
6
+ "scripts": {
7
+ "test": "cross-env BUILD_ENV='test' nyc jasmine JASMINE_CONFIG_PATH=jasmine.json",
8
+ "itest": "cross-env BUILD_ENV='development' nyc jasmine JASMINE_CONFIG_PATH=jasmine.json",
9
+ "build": "webpack --config webpack.config.js",
10
+ "build-prod": "cross-env BUILD_ENV='production' webpack --config webpack.config.js"
11
+ },
12
+ "repository": {
13
+ "type": "git"
14
+ },
15
+ "author": "Kevin Batchelor",
16
+ "license": "PVT",
17
+ "devDependencies": {
18
+ "@babel/cli": "7.11.6",
19
+ "@babel/core": "7.23.2",
20
+ "@babel/preset-env": "^7.29.0",
21
+ "@babel/register": "^7.28.6",
22
+ "@babel/runtime": "8.0.0-alpha.17",
23
+ "aws-sdk-client-mock": "^3.0.1",
24
+ "babel-loader": "9.1.3",
25
+ "babel-preset-env": "1.7.0",
26
+ "cross-env": "7.0.3",
27
+ "jasmine": "5.1.0",
28
+ "nyc": "14.1.1",
29
+ "terser-webpack-plugin": "^5.3.10",
30
+ "webpack": "5.104.1",
31
+ "webpack-cli": "^5.1.4",
32
+ "webpack-node-externals": "3.0.0"
33
+ },
34
+ "dependencies": {
35
+ "@aws-sdk/client-dynamodb": "^3.507.0",
36
+ "@aws-sdk/client-s3": "^3.507.0",
37
+ "@aws-sdk/client-sns": "^3.507.0",
38
+ "@aws-sdk/lib-dynamodb": "^3.507.0",
39
+ "babel-runtime": "6.26.0"
40
+ },
41
+ "peerDependencies": {
42
+ "bluebird": ">=3.7.0",
43
+ "dayjs": "^1.11.13",
44
+ "lodash": ">=4.17.15",
45
+ "sequelize": ">=6.6.2",
46
+ "umzug": ">=3.2.1"
47
+ },
48
+ "nyc": {
49
+ "require": [
50
+ "@babel/register"
51
+ ],
52
+ "reporter": [
53
+ "lcov",
54
+ "text-summary"
55
+ ],
56
+ "check-coverage": true,
57
+ "branches": 70,
58
+ "lines": 80,
59
+ "functions": 70,
60
+ "statements": 85
61
+ }
62
+ }
@@ -0,0 +1,29 @@
1
+ export const DEFAULT_LIMIT = 10;
2
+ export const MAX_LIMIT = 500;
3
+
4
+ /**
5
+ * Read a sanitized limit/offset out of a request's query string.
6
+ *
7
+ * Every consuming repo was hand-rolling `parseInt(qsp.limit ?? '10')`, which has
8
+ * a sharp edge: parseInt('abc') and parseInt('') are NaN, and findAll() below
9
+ * does `options.limit || 0` -> Sequelize `limit: 1`. So `?limit=abc` silently
10
+ * returned exactly one row instead of a page. This clamps instead, and bounds
11
+ * the upper end so `?limit=100000` can't be used to pull a whole table.
12
+ *
13
+ * The cap is deliberately loose — it exists to stop abuse, not to be a tight
14
+ * page size. Pass maxLimit when a route needs a different ceiling.
15
+ *
16
+ * @param {object} event - The lambda event passed in by a validated api request.
17
+ * @param {object} [options] - Overrides.
18
+ * @param {number} [options.defaultLimit] - Limit when none is supplied (default 10).
19
+ * @param {number} [options.maxLimit] - Upper bound for limit (default 500).
20
+ * @returns {{limit: number, offset: number}} Sanitized pagination.
21
+ */
22
+ export function getPagination(event, { defaultLimit = DEFAULT_LIMIT, maxLimit = MAX_LIMIT } = {}) {
23
+ const query = event?.queryStringParameters || {};
24
+
25
+ const limit = Math.max(1, Math.min(parseInt(query.limit, 10) || defaultLimit, maxLimit));
26
+ const offset = Math.max(0, parseInt(query.offset, 10) || 0);
27
+
28
+ return { limit, offset };
29
+ }
@@ -0,0 +1,83 @@
1
+ import { getPagination } from './getPagination.js';
2
+
3
+ describe('getPagination', function () {
4
+ it('should default to limit 10 offset 0 when nothing is supplied', function () {
5
+ // Act
6
+ const result = getPagination({});
7
+
8
+ // Assert
9
+ expect(result).toEqual({ limit: 10, offset: 0 });
10
+ });
11
+
12
+ it('should tolerate a missing event', function () {
13
+ // Act
14
+ const result = getPagination(undefined);
15
+
16
+ // Assert
17
+ expect(result).toEqual({ limit: 10, offset: 0 });
18
+ });
19
+
20
+ it('should use the supplied limit and offset', function () {
21
+ // Arrange
22
+ const event = { queryStringParameters: { limit: '25', offset: '50' } };
23
+
24
+ // Act
25
+ const result = getPagination(event);
26
+
27
+ // Assert
28
+ expect(result).toEqual({ limit: 25, offset: 50 });
29
+ });
30
+
31
+ it('should fall back to the default when limit is not a number', function () {
32
+ // Arrange - parseInt('abc') is NaN, and findAll turns a falsy limit into
33
+ // Sequelize `limit: 1`, so this used to return exactly one row.
34
+ const event = { queryStringParameters: { limit: 'abc' } };
35
+
36
+ // Act
37
+ const result = getPagination(event);
38
+
39
+ // Assert
40
+ expect(result.limit).toBe(10);
41
+ });
42
+
43
+ it('should fall back to the default when limit is empty or zero', function () {
44
+ // Act + Assert
45
+ expect(getPagination({ queryStringParameters: { limit: '' } }).limit).toBe(10);
46
+ expect(getPagination({ queryStringParameters: { limit: '0' } }).limit).toBe(10);
47
+ });
48
+
49
+ it('should clamp an oversized limit rather than running it', function () {
50
+ // Arrange
51
+ const event = { queryStringParameters: { limit: '100000' } };
52
+
53
+ // Act
54
+ const result = getPagination(event);
55
+
56
+ // Assert
57
+ expect(result.limit).toBe(500);
58
+ });
59
+
60
+ it('should never return a negative offset', function () {
61
+ // Arrange
62
+ const event = { queryStringParameters: { offset: '-20' } };
63
+
64
+ // Act
65
+ const result = getPagination(event);
66
+
67
+ // Assert
68
+ expect(result.offset).toBe(0);
69
+ });
70
+
71
+ it('should honor caller supplied defaultLimit and maxLimit', function () {
72
+ // Arrange
73
+ const event = { queryStringParameters: { limit: '999' } };
74
+
75
+ // Act
76
+ const clamped = getPagination(event, { maxLimit: 50 });
77
+ const defaulted = getPagination({}, { defaultLimit: 20 });
78
+
79
+ // Assert
80
+ expect(clamped.limit).toBe(50);
81
+ expect(defaulted.limit).toBe(20);
82
+ });
83
+ });
package/src/index.js CHANGED
@@ -29,6 +29,8 @@ import { getBelongsToPartnerId as getBelongsToPartnerIdImport } from './database
29
29
  import { getEffectivePartnerId as getEffectivePartnerIdImport } from './database/dbUtils/queryStringUtils/accessRightsUtils.js';
30
30
  import { enrichEventWithPartnerAccess as enrichEventWithPartnerAccessImport } from './database/dbUtils/queryStringUtils/accessRightsUtils.js';
31
31
  import { getCompanySettings as getCompanySettingsImport } from './database/dbUtils/queryStringUtils/accessRightsUtils.js';
32
+ import { getRequestedBusinessIds as getRequestedBusinessIdsImport } from './database/dbUtils/queryStringUtils/accessRightsUtils.js';
33
+ import { getPagination as getPaginationImport } from './database/dbUtils/queryStringUtils/getPagination.js';
32
34
  import { resolveAccess as resolveAccessImport, ensurePartnerScope as ensurePartnerScopeImport } from './database/dbUtils/partnerAccess/accessContext.js';
33
35
  import { requireCrmAccess as requireCrmAccessImport, requireTicketAccess as requireTicketAccessImport, requireSuper as requireSuperImport } from './database/dbUtils/partnerAccess/accessGates.js';
34
36
  import { scopeToOwnBusiness as scopeToOwnBusinessImport, scopeToPartnerBook as scopeToPartnerBookImport, scopeToBookUnionOwn as scopeToBookUnionOwnImport } from './database/dbUtils/partnerAccess/accessScope.js';
@@ -52,6 +54,8 @@ export const createFilters = createFiltersImport;
52
54
  export const createIncludes = createIncludesImport;
53
55
  export const createSort = createSortImport;
54
56
  export const findAll = findAllImport;
57
+ export const getPagination = getPaginationImport;
58
+ export const getRequestedBusinessIds = getRequestedBusinessIdsImport;
55
59
  export const checkModule = checkModuleImport;
56
60
  export const checkIsSuper = checkIsSuperImport;
57
61
  export const getAccessRightsInfo = getAccessRightsInfoImport;