@memberjunction/server 5.51.2 → 5.51.4
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/README.md +34 -1
- package/dist/agentSessions/SessionManager.d.ts +5 -2
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +17 -8
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/agentSessions/SessionRunIDVerifier.d.ts +63 -0
- package/dist/agentSessions/SessionRunIDVerifier.d.ts.map +1 -0
- package/dist/agentSessions/SessionRunIDVerifier.js +136 -0
- package/dist/agentSessions/SessionRunIDVerifier.js.map +1 -0
- package/dist/agentSessions/index.d.ts +1 -0
- package/dist/agentSessions/index.d.ts.map +1 -1
- package/dist/agentSessions/index.js +1 -0
- package/dist/agentSessions/index.js.map +1 -1
- package/dist/auth/actionAuthorization.d.ts +40 -0
- package/dist/auth/actionAuthorization.d.ts.map +1 -0
- package/dist/auth/actionAuthorization.js +94 -0
- package/dist/auth/actionAuthorization.js.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/scopeLimitedPrincipal.d.ts +39 -0
- package/dist/auth/scopeLimitedPrincipal.d.ts.map +1 -0
- package/dist/auth/scopeLimitedPrincipal.js +49 -0
- package/dist/auth/scopeLimitedPrincipal.js.map +1 -0
- package/dist/config.d.ts +53 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +34 -1
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +6 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +24 -34
- package/dist/context.js.map +1 -1
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +3262 -3273
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/CacheInvalidationResolver.d.ts +124 -4
- package/dist/generic/CacheInvalidationResolver.d.ts.map +1 -1
- package/dist/generic/CacheInvalidationResolver.js +170 -15
- package/dist/generic/CacheInvalidationResolver.js.map +1 -1
- package/dist/generic/FireAndForgetHeartbeat.d.ts +5 -0
- package/dist/generic/FireAndForgetHeartbeat.d.ts.map +1 -1
- package/dist/generic/FireAndForgetHeartbeat.js +5 -4
- package/dist/generic/FireAndForgetHeartbeat.js.map +1 -1
- package/dist/generic/PushStatusResolver.d.ts +58 -0
- package/dist/generic/PushStatusResolver.d.ts.map +1 -1
- package/dist/generic/PushStatusResolver.js +42 -3
- package/dist/generic/PushStatusResolver.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +148 -3
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +287 -30
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +12 -0
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +58 -50
- package/dist/index.js.map +1 -1
- package/dist/multiTenancy/index.d.ts.map +1 -1
- package/dist/multiTenancy/index.js +22 -2
- package/dist/multiTenancy/index.js.map +1 -1
- package/dist/postgresqlCompat.d.ts +8 -0
- package/dist/postgresqlCompat.d.ts.map +1 -0
- package/dist/postgresqlCompat.js +19 -0
- package/dist/postgresqlCompat.js.map +1 -0
- package/dist/postgresqlPoolSettings.d.ts +108 -0
- package/dist/postgresqlPoolSettings.d.ts.map +1 -0
- package/dist/postgresqlPoolSettings.js +134 -0
- package/dist/postgresqlPoolSettings.js.map +1 -0
- package/dist/realtimeWidget/widgetGuestElevation.d.ts +2 -2
- package/dist/realtimeWidget/widgetGuestElevation.js +2 -2
- package/dist/resolvers/ActionResolver.d.ts +31 -5
- package/dist/resolvers/ActionResolver.d.ts.map +1 -1
- package/dist/resolvers/ActionResolver.js +75 -14
- package/dist/resolvers/ActionResolver.js.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.d.ts +39 -17
- package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
- package/dist/resolvers/AdhocQueryResolver.js +97 -157
- package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
- package/dist/resolvers/DatasetResolver.d.ts +24 -3
- package/dist/resolvers/DatasetResolver.d.ts.map +1 -1
- package/dist/resolvers/DatasetResolver.js +57 -8
- package/dist/resolvers/DatasetResolver.js.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.d.ts +14 -4
- package/dist/resolvers/EntityRecordNameResolver.d.ts.map +1 -1
- package/dist/resolvers/EntityRecordNameResolver.js +18 -6
- package/dist/resolvers/EntityRecordNameResolver.js.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.d.ts +33 -7
- package/dist/resolvers/GetDataContextDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataContextDataResolver.js +117 -38
- package/dist/resolvers/GetDataContextDataResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +13 -1
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +13 -16
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +26 -14
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +63 -46
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +2 -0
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +24 -27
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +30 -40
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +12 -11
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/RunTestResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTestResolver.js +90 -112
- package/dist/resolvers/RunTestResolver.js.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.d.ts.map +1 -1
- package/dist/resolvers/SyncRolesUsersResolver.js +11 -2
- package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
- package/dist/resolvers/VersionHistoryResolver.d.ts.map +1 -1
- package/dist/resolvers/VersionHistoryResolver.js +8 -12
- package/dist/resolvers/VersionHistoryResolver.js.map +1 -1
- package/dist/resolvers/adhocTimeout.d.ts +7 -0
- package/dist/resolvers/adhocTimeout.d.ts.map +1 -0
- package/dist/resolvers/adhocTimeout.js +12 -0
- package/dist/resolvers/adhocTimeout.js.map +1 -0
- package/dist/rest/ViewOperationsHandler.d.ts +3 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +29 -17
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/services/TaskOrchestrator.d.ts.map +1 -1
- package/dist/services/TaskOrchestrator.js +17 -15
- package/dist/services/TaskOrchestrator.js.map +1 -1
- package/package.json +90 -89
- package/src/__tests__/ActionResolver.authorization.test.ts +353 -0
- package/src/__tests__/AdhocQueryResolver.bugs.test.ts +14 -35
- package/src/__tests__/AdhocQueryResolver.pagination.test.ts +6 -2
- package/src/__tests__/AdhocQueryResolver.scopeGuard.test.ts +84 -0
- package/src/__tests__/AdhocQueryResolver.sqlAuthorizer.test.ts +104 -0
- package/src/__tests__/DatasetResolver.itemFilters.test.ts +201 -0
- package/src/__tests__/EntityRecordNameResolver.rowSecurity.test.ts +152 -0
- package/src/__tests__/GetDataContextDataResolver.sqlItems.test.ts +416 -0
- package/src/__tests__/ListOperationsResolver.adhocScreen.test.ts +136 -0
- package/src/__tests__/RealtimeClientSessionResolver.configTamper.test.ts +318 -0
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +66 -27
- package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +134 -0
- package/src/__tests__/ResolverBase.adhocReadScope.test.ts +221 -0
- package/src/__tests__/ResolverBase.aggregateScreen.test.ts +173 -0
- package/src/__tests__/ResolverBase.balancedClause.test.ts +155 -0
- package/src/__tests__/ResolverBase.clauseUnscopedRead.test.ts +116 -0
- package/src/__tests__/ResolverBase.filterEscaping.test.ts +351 -0
- package/src/__tests__/RunTemplateResolver.test.ts +132 -0
- package/src/__tests__/RunViewResolver.cacheCheckScreen.test.ts +164 -0
- package/src/__tests__/SessionManager.test.ts +88 -13
- package/src/__tests__/SessionRunIDVerifier.test.ts +255 -0
- package/src/__tests__/UpdateMJDataContextItem.oldValues.test.ts +220 -0
- package/src/__tests__/ViewOperationsHandler.clauseScreen.test.ts +155 -0
- package/src/__tests__/actionAuthorization.test.ts +130 -0
- package/src/__tests__/adhocTimeoutClamp.test.ts +26 -0
- package/src/__tests__/cacheInvalidationRecordData.test.ts +241 -0
- package/src/__tests__/multiTenancy.postgresRewrite.test.ts +180 -0
- package/src/__tests__/multiTenancy.security.test.ts +51 -0
- package/src/__tests__/multiTenancy.test.ts +1 -1
- package/src/__tests__/newUserRolesDefault.test.ts +81 -0
- package/src/__tests__/postgresqlPoolSettings.test.ts +131 -0
- package/src/__tests__/pushStatusResolver.filter.test.ts +56 -0
- package/src/__tests__/resolverBase.refusalMessage.test.ts +88 -0
- package/src/__tests__/resolverBase.rls.test.ts +2 -0
- package/src/__tests__/translateBracketsToPG.test.ts +20 -0
- package/src/agentSessions/SessionManager.ts +24 -25
- package/src/agentSessions/SessionRunIDVerifier.ts +179 -0
- package/src/agentSessions/index.ts +1 -0
- package/src/auth/actionAuthorization.ts +119 -0
- package/src/auth/index.ts +1 -0
- package/src/auth/scopeLimitedPrincipal.ts +50 -0
- package/src/config.ts +34 -1
- package/src/context.ts +25 -34
- package/src/generated/generated.ts +3262 -3273
- package/src/generic/CacheInvalidationResolver.ts +206 -15
- package/src/generic/FireAndForgetHeartbeat.ts +10 -4
- package/src/generic/PushStatusResolver.ts +79 -4
- package/src/generic/ResolverBase.ts +339 -31
- package/src/generic/RunViewResolver.ts +17 -0
- package/src/index.ts +65 -52
- package/src/multiTenancy/index.ts +24 -2
- package/src/postgresqlCompat.ts +21 -0
- package/src/postgresqlPoolSettings.ts +213 -0
- package/src/realtimeWidget/widgetGuestElevation.ts +2 -2
- package/src/resolvers/ActionResolver.ts +85 -22
- package/src/resolvers/AdhocQueryResolver.ts +110 -177
- package/src/resolvers/DatasetResolver.ts +70 -10
- package/src/resolvers/EntityRecordNameResolver.ts +24 -7
- package/src/resolvers/GetDataContextDataResolver.ts +139 -41
- package/src/resolvers/GetDataResolver.ts +14 -1
- package/src/resolvers/MCPResolver.ts +13 -15
- package/src/resolvers/RealtimeClientSessionResolver.ts +82 -50
- package/src/resolvers/RemoteBrowserActionResolver.ts +30 -26
- package/src/resolvers/RunAIAgentResolver.ts +30 -40
- package/src/resolvers/RunTemplateResolver.ts +13 -12
- package/src/resolvers/RunTestResolver.ts +90 -112
- package/src/resolvers/SyncRolesUsersResolver.ts +11 -2
- package/src/resolvers/VersionHistoryResolver.ts +10 -13
- package/src/resolvers/__tests__/GetDataResolver.validation.test.ts +95 -0
- package/src/resolvers/__tests__/ReportResolver.test.ts +2 -0
- package/src/resolvers/adhocTimeout.ts +12 -0
- package/src/rest/ViewOperationsHandler.ts +37 -18
- package/src/services/TaskOrchestrator.ts +17 -17
- package/dist/resolvers/adhoc-query-helpers.d.ts +0 -27
- package/dist/resolvers/adhoc-query-helpers.d.ts.map +0 -1
- package/dist/resolvers/adhoc-query-helpers.js +0 -42
- package/dist/resolvers/adhoc-query-helpers.js.map +0 -1
- package/src/__tests__/adhoc-query-helpers.test.ts +0 -50
- package/src/resolvers/adhoc-query-helpers.ts +0 -50
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure, dependency-free helpers for {@link AdhocQueryResolver}. Kept in their own
|
|
3
|
-
* module (no type-graphql / mssql imports) so the total-row-count boundary logic is
|
|
4
|
-
* unit-testable without standing up the GraphQL resolver or a database.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Determines the exact total row count from the page alone, when it can be known
|
|
8
|
-
* without a separate `COUNT(*)`:
|
|
9
|
-
*
|
|
10
|
-
* - **Not paging** (`maxRows == null`): the query ran uncapped, so every row came
|
|
11
|
-
* back — the total is just the number returned.
|
|
12
|
-
* - **Short page** (`pageLength < maxRows`): a page shorter than the page size means
|
|
13
|
-
* there are no rows beyond it, so the total is `startRow + pageLength` exactly.
|
|
14
|
-
* - **Full page** (`pageLength >= maxRows`): more rows may exist — returns `null` to
|
|
15
|
-
* signal that a `COUNT(*)` is required to know the true total.
|
|
16
|
-
*/
|
|
17
|
-
export declare function exactTotalFromPage(startRow: number, pageLength: number, maxRows: number | null): number | null;
|
|
18
|
-
/**
|
|
19
|
-
* Reads the total row count from a `COUNT(*)` recordset (`[{ TotalRowCount }]`),
|
|
20
|
-
* falling back to `fallback` when the count is absent, non-numeric, or negative — so
|
|
21
|
-
* an unexpected count shape never yields a misleading total. `fallback` should be a
|
|
22
|
-
* safe lower bound (e.g. `startRow + rowsReturned`).
|
|
23
|
-
*/
|
|
24
|
-
export declare function resolveAdhocTotalRowCount(countRows: ReadonlyArray<{
|
|
25
|
-
TotalRowCount?: unknown;
|
|
26
|
-
}> | null | undefined, fallback: number): number;
|
|
27
|
-
//# sourceMappingURL=adhoc-query-helpers.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adhoc-query-helpers.d.ts","sourceRoot":"","sources":["../../src/resolvers/adhoc-query-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAC9B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAAG,IAAI,GACvB,MAAM,GAAG,IAAI,CAQf;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACrC,SAAS,EAAE,aAAa,CAAC;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EACxE,QAAQ,EAAE,MAAM,GACjB,MAAM,CASR"}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure, dependency-free helpers for {@link AdhocQueryResolver}. Kept in their own
|
|
3
|
-
* module (no type-graphql / mssql imports) so the total-row-count boundary logic is
|
|
4
|
-
* unit-testable without standing up the GraphQL resolver or a database.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Determines the exact total row count from the page alone, when it can be known
|
|
8
|
-
* without a separate `COUNT(*)`:
|
|
9
|
-
*
|
|
10
|
-
* - **Not paging** (`maxRows == null`): the query ran uncapped, so every row came
|
|
11
|
-
* back — the total is just the number returned.
|
|
12
|
-
* - **Short page** (`pageLength < maxRows`): a page shorter than the page size means
|
|
13
|
-
* there are no rows beyond it, so the total is `startRow + pageLength` exactly.
|
|
14
|
-
* - **Full page** (`pageLength >= maxRows`): more rows may exist — returns `null` to
|
|
15
|
-
* signal that a `COUNT(*)` is required to know the true total.
|
|
16
|
-
*/
|
|
17
|
-
export function exactTotalFromPage(startRow, pageLength, maxRows) {
|
|
18
|
-
if (maxRows == null) {
|
|
19
|
-
return pageLength;
|
|
20
|
-
}
|
|
21
|
-
if (pageLength < maxRows) {
|
|
22
|
-
return startRow + pageLength;
|
|
23
|
-
}
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Reads the total row count from a `COUNT(*)` recordset (`[{ TotalRowCount }]`),
|
|
28
|
-
* falling back to `fallback` when the count is absent, non-numeric, or negative — so
|
|
29
|
-
* an unexpected count shape never yields a misleading total. `fallback` should be a
|
|
30
|
-
* safe lower bound (e.g. `startRow + rowsReturned`).
|
|
31
|
-
*/
|
|
32
|
-
export function resolveAdhocTotalRowCount(countRows, fallback) {
|
|
33
|
-
const raw = countRows?.[0]?.TotalRowCount;
|
|
34
|
-
if (raw != null) {
|
|
35
|
-
const n = Number(raw);
|
|
36
|
-
if (Number.isFinite(n) && n >= 0) {
|
|
37
|
-
return Math.floor(n);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return fallback;
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=adhoc-query-helpers.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adhoc-query-helpers.js","sourceRoot":"","sources":["../../src/resolvers/adhoc-query-helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAC9B,QAAgB,EAChB,UAAkB,EAClB,OAAsB;IAEtB,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,UAAU,CAAC;IACtB,CAAC;IACD,IAAI,UAAU,GAAG,OAAO,EAAE,CAAC;QACvB,OAAO,QAAQ,GAAG,UAAU,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB,CACrC,SAAwE,EACxE,QAAgB;IAEhB,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC;IAC1C,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QACd,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AACpB,CAAC"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { exactTotalFromPage, resolveAdhocTotalRowCount } from '../resolvers/adhoc-query-helpers';
|
|
3
|
-
|
|
4
|
-
describe('exactTotalFromPage', () => {
|
|
5
|
-
it('returns the row count when not paging (maxRows null) — the query was uncapped', () => {
|
|
6
|
-
expect(exactTotalFromPage(0, 47, null)).toBe(47);
|
|
7
|
-
expect(exactTotalFromPage(0, 0, null)).toBe(0);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
it('returns startRow + pageLength for a SHORT page (fewer rows than the page size)', () => {
|
|
11
|
-
expect(exactTotalFromPage(0, 47, 100)).toBe(47); // page 1, short → exact total
|
|
12
|
-
expect(exactTotalFromPage(200, 30, 100)).toBe(230); // page 3, short last page
|
|
13
|
-
expect(exactTotalFromPage(100, 0, 100)).toBe(100); // empty page past the end
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
it('returns null for a FULL page — a COUNT is required because more rows may exist', () => {
|
|
17
|
-
expect(exactTotalFromPage(0, 100, 100)).toBeNull();
|
|
18
|
-
expect(exactTotalFromPage(500, 100, 100)).toBeNull();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('treats an over-full page defensively as "needs count" (should not occur with OFFSET/FETCH)', () => {
|
|
22
|
-
expect(exactTotalFromPage(0, 150, 100)).toBeNull();
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
describe('resolveAdhocTotalRowCount', () => {
|
|
27
|
-
it('reads TotalRowCount from the count recordset', () => {
|
|
28
|
-
expect(resolveAdhocTotalRowCount([{ TotalRowCount: 2087 }], 100)).toBe(2087);
|
|
29
|
-
expect(resolveAdhocTotalRowCount([{ TotalRowCount: 0 }], 100)).toBe(0);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it('floors a fractional/stringified count', () => {
|
|
33
|
-
expect(resolveAdhocTotalRowCount([{ TotalRowCount: 42.9 }], 0)).toBe(42);
|
|
34
|
-
expect(resolveAdhocTotalRowCount([{ TotalRowCount: '2087' as unknown as number }], 0)).toBe(2087);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('falls back when the count is absent, empty, null, or malformed', () => {
|
|
38
|
-
expect(resolveAdhocTotalRowCount(null, 100)).toBe(100);
|
|
39
|
-
expect(resolveAdhocTotalRowCount(undefined, 100)).toBe(100);
|
|
40
|
-
expect(resolveAdhocTotalRowCount([], 100)).toBe(100);
|
|
41
|
-
expect(resolveAdhocTotalRowCount([{}], 100)).toBe(100);
|
|
42
|
-
expect(resolveAdhocTotalRowCount([{ TotalRowCount: null }], 100)).toBe(100);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('falls back on non-finite or negative counts (never reports a misleading total)', () => {
|
|
46
|
-
expect(resolveAdhocTotalRowCount([{ TotalRowCount: Number.NaN }], 100)).toBe(100);
|
|
47
|
-
expect(resolveAdhocTotalRowCount([{ TotalRowCount: -5 }], 100)).toBe(100);
|
|
48
|
-
expect(resolveAdhocTotalRowCount([{ TotalRowCount: Infinity }], 100)).toBe(100);
|
|
49
|
-
});
|
|
50
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure, dependency-free helpers for {@link AdhocQueryResolver}. Kept in their own
|
|
3
|
-
* module (no type-graphql / mssql imports) so the total-row-count boundary logic is
|
|
4
|
-
* unit-testable without standing up the GraphQL resolver or a database.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Determines the exact total row count from the page alone, when it can be known
|
|
9
|
-
* without a separate `COUNT(*)`:
|
|
10
|
-
*
|
|
11
|
-
* - **Not paging** (`maxRows == null`): the query ran uncapped, so every row came
|
|
12
|
-
* back — the total is just the number returned.
|
|
13
|
-
* - **Short page** (`pageLength < maxRows`): a page shorter than the page size means
|
|
14
|
-
* there are no rows beyond it, so the total is `startRow + pageLength` exactly.
|
|
15
|
-
* - **Full page** (`pageLength >= maxRows`): more rows may exist — returns `null` to
|
|
16
|
-
* signal that a `COUNT(*)` is required to know the true total.
|
|
17
|
-
*/
|
|
18
|
-
export function exactTotalFromPage(
|
|
19
|
-
startRow: number,
|
|
20
|
-
pageLength: number,
|
|
21
|
-
maxRows: number | null,
|
|
22
|
-
): number | null {
|
|
23
|
-
if (maxRows == null) {
|
|
24
|
-
return pageLength;
|
|
25
|
-
}
|
|
26
|
-
if (pageLength < maxRows) {
|
|
27
|
-
return startRow + pageLength;
|
|
28
|
-
}
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Reads the total row count from a `COUNT(*)` recordset (`[{ TotalRowCount }]`),
|
|
34
|
-
* falling back to `fallback` when the count is absent, non-numeric, or negative — so
|
|
35
|
-
* an unexpected count shape never yields a misleading total. `fallback` should be a
|
|
36
|
-
* safe lower bound (e.g. `startRow + rowsReturned`).
|
|
37
|
-
*/
|
|
38
|
-
export function resolveAdhocTotalRowCount(
|
|
39
|
-
countRows: ReadonlyArray<{ TotalRowCount?: unknown }> | null | undefined,
|
|
40
|
-
fallback: number,
|
|
41
|
-
): number {
|
|
42
|
-
const raw = countRows?.[0]?.TotalRowCount;
|
|
43
|
-
if (raw != null) {
|
|
44
|
-
const n = Number(raw);
|
|
45
|
-
if (Number.isFinite(n) && n >= 0) {
|
|
46
|
-
return Math.floor(n);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return fallback;
|
|
50
|
-
}
|