@shware/http 2.4.2 → 2.4.3

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.cjs CHANGED
@@ -49,6 +49,7 @@ __export(index_exports, {
49
49
  getPreviousPageParam: () => import_response.getPreviousPageParam,
50
50
  initialPageParam: () => import_response.initialPageParam,
51
51
  pageParamsSchema: () => import_response.pageParamsSchema,
52
+ pages: () => import_response.pages,
52
53
  timing: () => import_timing.timing,
53
54
  uid: () => import_snowflake.uid
54
55
  });
@@ -83,6 +84,7 @@ var import_iso_3601_1 = require("./iso/iso_3601_1.cjs");
83
84
  getPreviousPageParam,
84
85
  initialPageParam,
85
86
  pageParamsSchema,
87
+ pages,
86
88
  timing,
87
89
  uid
88
90
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @example\n * import { Details, Status } from '@repo/error';\n *\n * Status.adapter = () => new Error('Error');\n *\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n *\n * throw Status.alreadyExists('xxx').error(details);\n */\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\nexport type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './error/reason';\nexport {\n DetailType,\n Details,\n type ErrorInfo,\n type RetryInfo,\n type DebugInfo,\n type QuotaFailure,\n type PreconditionFailure,\n type BadRequest,\n type RequestInfo,\n type ResourceInfo,\n type Help,\n type LocalizedMessage,\n type Detail,\n} from './error/detail';\nexport { Status, StatusError, type ErrorBody } from './error/status';\nexport { getErrorReason, getErrorMessage, getFieldViolations } from './error/parse';\nexport {\n pageParamsSchema,\n Cursor,\n initialPageParam,\n getPreviousPageParam,\n getNextPageParam,\n} from './response';\nexport type {\n Empty,\n EntityId,\n Entity,\n Response,\n InitParams,\n NextParams,\n PrevParams,\n PageParams,\n ParentPageParams,\n Page,\n} from './response';\n\nexport { UidGenerator, uid } from './snowflake';\n\nexport * as MAX_LENGTH from './max-length/index';\nexport { timing } from './utils/timing';\nexport { ISO_3601_1, type ISO3166CountryCode } from './iso/iso_3601_1';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,mBAKO;AAUP,oBAcO;AACP,oBAAoD;AACpD,mBAAoE;AACpE,sBAMO;AAcP,uBAAkC;AAElC,iBAA4B;AAC5B,oBAAuB;AACvB,wBAAoD;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @example\n * import { Details, Status } from '@repo/error';\n *\n * Status.adapter = () => new Error('Error');\n *\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n *\n * throw Status.alreadyExists('xxx').error(details);\n */\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\nexport type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './error/reason';\nexport {\n DetailType,\n Details,\n type ErrorInfo,\n type RetryInfo,\n type DebugInfo,\n type QuotaFailure,\n type PreconditionFailure,\n type BadRequest,\n type RequestInfo,\n type ResourceInfo,\n type Help,\n type LocalizedMessage,\n type Detail,\n} from './error/detail';\nexport { Status, StatusError, type ErrorBody } from './error/status';\nexport { getErrorReason, getErrorMessage, getFieldViolations } from './error/parse';\nexport {\n pages,\n Cursor,\n pageParamsSchema,\n initialPageParam,\n getPreviousPageParam,\n getNextPageParam,\n} from './response';\nexport type {\n Empty,\n EntityId,\n Entity,\n Response,\n InitParams,\n NextParams,\n PrevParams,\n PageParams,\n ParentPageParams,\n Page,\n InfinitePageData,\n} from './response';\n\nexport { UidGenerator, uid } from './snowflake';\n\nexport * as MAX_LENGTH from './max-length/index';\nexport { timing } from './utils/timing';\nexport { ISO_3601_1, type ISO3166CountryCode } from './iso/iso_3601_1';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,mBAKO;AAUP,oBAcO;AACP,oBAAoD;AACpD,mBAAoE;AACpE,sBAOO;AAeP,uBAAkC;AAElC,iBAA4B;AAC5B,oBAAuB;AACvB,wBAAoD;","names":[]}
package/dist/index.d.cts CHANGED
@@ -3,7 +3,7 @@ export { AppErrorReason, AuthenticationErrorReason, ErrorReason, ModerationError
3
3
  export { BadRequest, DebugInfo, Detail, DetailType, Details, ErrorInfo, Help, LocalizedMessage, PreconditionFailure, QuotaFailure, RequestInfo, ResourceInfo, RetryInfo } from './error/detail.cjs';
4
4
  export { ErrorBody, Status, StatusError } from './error/status.cjs';
5
5
  export { getErrorMessage, getErrorReason, getFieldViolations } from './error/parse.cjs';
6
- export { Cursor, Empty, Entity, EntityId, InitParams, NextParams, Page, PageParams, ParentPageParams, PrevParams, Response, getNextPageParam, getPreviousPageParam, initialPageParam, pageParamsSchema } from './response.cjs';
6
+ export { Cursor, Empty, Entity, EntityId, InfinitePageData, InitParams, NextParams, Page, PageParams, ParentPageParams, PrevParams, Response, getNextPageParam, getPreviousPageParam, initialPageParam, pageParamsSchema, pages } from './response.cjs';
7
7
  export { UidGenerator, uid } from './snowflake.cjs';
8
8
  export { i as MAX_LENGTH } from './index-BnPgRQDl.cjs';
9
9
  export { timing } from './utils/timing.cjs';
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { AppErrorReason, AuthenticationErrorReason, ErrorReason, ModerationError
3
3
  export { BadRequest, DebugInfo, Detail, DetailType, Details, ErrorInfo, Help, LocalizedMessage, PreconditionFailure, QuotaFailure, RequestInfo, ResourceInfo, RetryInfo } from './error/detail.js';
4
4
  export { ErrorBody, Status, StatusError } from './error/status.js';
5
5
  export { getErrorMessage, getErrorReason, getFieldViolations } from './error/parse.js';
6
- export { Cursor, Empty, Entity, EntityId, InitParams, NextParams, Page, PageParams, ParentPageParams, PrevParams, Response, getNextPageParam, getPreviousPageParam, initialPageParam, pageParamsSchema } from './response.js';
6
+ export { Cursor, Empty, Entity, EntityId, InfinitePageData, InitParams, NextParams, Page, PageParams, ParentPageParams, PrevParams, Response, getNextPageParam, getPreviousPageParam, initialPageParam, pageParamsSchema, pages } from './response.js';
7
7
  export { UidGenerator, uid } from './snowflake.js';
8
8
  export { i as MAX_LENGTH } from './index-BnPgRQDl.js';
9
9
  export { timing } from './utils/timing.js';
package/dist/index.mjs CHANGED
@@ -12,8 +12,9 @@ import {
12
12
  import { Status, StatusError } from "./error/status.mjs";
13
13
  import { getErrorReason, getErrorMessage, getFieldViolations } from "./error/parse.mjs";
14
14
  import {
15
- pageParamsSchema,
15
+ pages,
16
16
  Cursor,
17
+ pageParamsSchema,
17
18
  initialPageParam,
18
19
  getPreviousPageParam,
19
20
  getNextPageParam
@@ -42,6 +43,7 @@ export {
42
43
  getPreviousPageParam,
43
44
  initialPageParam,
44
45
  pageParamsSchema,
46
+ pages,
45
47
  timing,
46
48
  uid
47
49
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @example\n * import { Details, Status } from '@repo/error';\n *\n * Status.adapter = () => new Error('Error');\n *\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n *\n * throw Status.alreadyExists('xxx').error(details);\n */\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\nexport type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './error/reason';\nexport {\n DetailType,\n Details,\n type ErrorInfo,\n type RetryInfo,\n type DebugInfo,\n type QuotaFailure,\n type PreconditionFailure,\n type BadRequest,\n type RequestInfo,\n type ResourceInfo,\n type Help,\n type LocalizedMessage,\n type Detail,\n} from './error/detail';\nexport { Status, StatusError, type ErrorBody } from './error/status';\nexport { getErrorReason, getErrorMessage, getFieldViolations } from './error/parse';\nexport {\n pageParamsSchema,\n Cursor,\n initialPageParam,\n getPreviousPageParam,\n getNextPageParam,\n} from './response';\nexport type {\n Empty,\n EntityId,\n Entity,\n Response,\n InitParams,\n NextParams,\n PrevParams,\n PageParams,\n ParentPageParams,\n Page,\n} from './response';\n\nexport { UidGenerator, uid } from './snowflake';\n\nexport * as MAX_LENGTH from './max-length/index';\nexport { timing } from './utils/timing';\nexport { ISO_3601_1, type ISO3166CountryCode } from './iso/iso_3601_1';\n"],"mappings":";AAaA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAUP;AAAA,EACE;AAAA,EACA;AAAA,OAYK;AACP,SAAS,QAAQ,mBAAmC;AACpD,SAAS,gBAAgB,iBAAiB,0BAA0B;AACpE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAcP,SAAS,cAAc,WAAW;AAElC,YAAY,gBAAgB;AAC5B,SAAS,cAAc;AACvB,SAAS,kBAA2C;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @example\n * import { Details, Status } from '@repo/error';\n *\n * Status.adapter = () => new Error('Error');\n *\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n *\n * throw Status.alreadyExists('xxx').error(details);\n */\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\nexport type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './error/reason';\nexport {\n DetailType,\n Details,\n type ErrorInfo,\n type RetryInfo,\n type DebugInfo,\n type QuotaFailure,\n type PreconditionFailure,\n type BadRequest,\n type RequestInfo,\n type ResourceInfo,\n type Help,\n type LocalizedMessage,\n type Detail,\n} from './error/detail';\nexport { Status, StatusError, type ErrorBody } from './error/status';\nexport { getErrorReason, getErrorMessage, getFieldViolations } from './error/parse';\nexport {\n pages,\n Cursor,\n pageParamsSchema,\n initialPageParam,\n getPreviousPageParam,\n getNextPageParam,\n} from './response';\nexport type {\n Empty,\n EntityId,\n Entity,\n Response,\n InitParams,\n NextParams,\n PrevParams,\n PageParams,\n ParentPageParams,\n Page,\n InfinitePageData,\n} from './response';\n\nexport { UidGenerator, uid } from './snowflake';\n\nexport * as MAX_LENGTH from './max-length/index';\nexport { timing } from './utils/timing';\nexport { ISO_3601_1, type ISO3166CountryCode } from './iso/iso_3601_1';\n"],"mappings":";AAaA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAUP;AAAA,EACE;AAAA,EACA;AAAA,OAYK;AACP,SAAS,QAAQ,mBAAmC;AACpD,SAAS,gBAAgB,iBAAiB,0BAA0B;AACpE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAeP,SAAS,cAAc,WAAW;AAElC,YAAY,gBAAgB;AAC5B,SAAS,cAAc;AACvB,SAAS,kBAA2C;","names":[]}
package/dist/response.cjs CHANGED
@@ -24,7 +24,8 @@ __export(response_exports, {
24
24
  getNextPageParam: () => getNextPageParam,
25
25
  getPreviousPageParam: () => getPreviousPageParam,
26
26
  initialPageParam: () => initialPageParam,
27
- pageParamsSchema: () => pageParamsSchema
27
+ pageParamsSchema: () => pageParamsSchema,
28
+ pages: () => pages
28
29
  });
29
30
  module.exports = __toCommonJS(response_exports);
30
31
  var import_utils = require("@shware/utils");
@@ -66,12 +67,78 @@ function getPreviousPageParam(first) {
66
67
  function getNextPageParam(last) {
67
68
  return (0, import_utils.hasText)(last.paging.next) ? { next: last.paging.next } : null;
68
69
  }
70
+ var pages = {
71
+ flatten(data) {
72
+ return data.pages.flatMap((page) => page.data);
73
+ },
74
+ dedupe(data) {
75
+ const seen = /* @__PURE__ */ new Set();
76
+ const result = [];
77
+ for (const page of data.pages) {
78
+ for (const item of page.data) {
79
+ if (!seen.has(item.id)) {
80
+ seen.add(item.id);
81
+ result.push(item);
82
+ }
83
+ }
84
+ }
85
+ return result;
86
+ },
87
+ prepend(item) {
88
+ return (data) => {
89
+ if (!data) return data;
90
+ const [first, ...rest] = data.pages;
91
+ if (!first) return { ...data, pages: [{ data: [item], paging: {} }] };
92
+ return { ...data, pages: [{ ...first, data: [item, ...first.data] }, ...rest] };
93
+ };
94
+ },
95
+ append(item) {
96
+ return (data) => {
97
+ if (!data) return data;
98
+ const pages2 = data.pages;
99
+ const last = pages2[pages2.length - 1];
100
+ if (!last) return { ...data, pages: [{ data: [item], paging: {} }] };
101
+ return { ...data, pages: [...pages2.slice(0, -1), { ...last, data: [...last.data, item] }] };
102
+ };
103
+ },
104
+ remove(predicate) {
105
+ return (data) => {
106
+ if (!data) return data;
107
+ return {
108
+ ...data,
109
+ pages: data.pages.map((page) => ({
110
+ ...page,
111
+ data: page.data.filter((item) => !predicate(item))
112
+ }))
113
+ };
114
+ };
115
+ },
116
+ update(updater, predicate) {
117
+ return (data) => {
118
+ if (!data) return data;
119
+ return {
120
+ ...data,
121
+ pages: data.pages.map((page) => ({
122
+ ...page,
123
+ data: page.data.map((item) => predicate(item) ? updater : item)
124
+ }))
125
+ };
126
+ };
127
+ },
128
+ updateById(updated) {
129
+ return this.update(updated, (item) => item.id === updated.id);
130
+ },
131
+ removeById(id) {
132
+ return this.remove((item) => item.id === id);
133
+ }
134
+ };
69
135
  // Annotate the CommonJS export names for ESM import in node:
70
136
  0 && (module.exports = {
71
137
  Cursor,
72
138
  getNextPageParam,
73
139
  getPreviousPageParam,
74
140
  initialPageParam,
75
- pageParamsSchema
141
+ pageParamsSchema,
142
+ pages
76
143
  });
77
144
  //# sourceMappingURL=response.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/response.ts"],"sourcesContent":["import { hasText } from '@shware/utils';\nimport { _default, coerce, int, maximum, minimum, object, optional, string } from 'zod/mini';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Empty = {};\nexport type EntityId = string | number;\nexport type Entity = { id: EntityId };\n\nexport type Response<T = never> = { data: T };\n\nexport type InitParams = { limit: number; parent?: string };\nexport type NextParams = { limit: number; parent?: string; next: string };\nexport type PrevParams = { limit: number; parent?: string; prev: string };\nexport type PageParams = { limit: number; prev?: string; next?: string };\nexport type ParentPageParams = { limit: number; parent: string; prev?: string; next?: string };\nexport type Page<T = never> = { data: T[]; paging: { next?: string; prev?: string } };\n\nexport function pageParamsSchema(max = 100, defaultLimit = 20) {\n return object({\n limit: _default(coerce.number().check(int(), minimum(1), maximum(max)), defaultLimit),\n prev: optional(string()),\n next: optional(string()),\n });\n}\n\nexport const Cursor = {\n of(\n prev: bigint | number | string | undefined,\n next: bigint | number | string | undefined\n ): Page['paging'] {\n return {\n prev: prev ? this.encode(prev) : undefined,\n next: next ? this.encode(next) : undefined,\n };\n },\n empty(): Page['paging'] {\n return { prev: undefined, next: undefined };\n },\n encode(id: bigint | number | string | undefined): string | undefined {\n if (!id) return undefined;\n return Buffer.from(id.toString(), 'utf-8').toString('base64');\n },\n decode<T extends 'bigint' | 'number' | 'string' = 'bigint'>(\n token: string,\n type: T = 'bigint' as T\n ): T extends 'bigint' ? bigint : T extends 'number' ? number : string {\n const value = Buffer.from(token, 'base64').toString('utf-8');\n if (type === 'bigint')\n return BigInt(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n if (type === 'number')\n return Number(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n return value as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n },\n};\n\nexport const initialPageParam: Page['paging'] = {};\n\nexport function getPreviousPageParam<T = never>(first: Page<T>): Page['paging'] | null {\n return hasText(first.paging.prev) ? { prev: first.paging.prev } : null;\n}\n\nexport function getNextPageParam<T = never>(last: Page<T>): Page['paging'] | null {\n return hasText(last.paging.next) ? { next: last.paging.next } : null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAwB;AACxB,kBAAkF;AAgB3E,SAAS,iBAAiB,MAAM,KAAK,eAAe,IAAI;AAC7D,aAAO,oBAAO;AAAA,IACZ,WAAO,sBAAS,mBAAO,OAAO,EAAE,UAAM,iBAAI,OAAG,qBAAQ,CAAC,OAAG,qBAAQ,GAAG,CAAC,GAAG,YAAY;AAAA,IACpF,UAAM,0BAAS,oBAAO,CAAC;AAAA,IACvB,UAAM,0BAAS,oBAAO,CAAC;AAAA,EACzB,CAAC;AACH;AAEO,IAAM,SAAS;AAAA,EACpB,GACE,MACA,MACgB;AAChB,WAAO;AAAA,MACL,MAAM,OAAO,KAAK,OAAO,IAAI,IAAI;AAAA,MACjC,MAAM,OAAO,KAAK,OAAO,IAAI,IAAI;AAAA,IACnC;AAAA,EACF;AAAA,EACA,QAAwB;AACtB,WAAO,EAAE,MAAM,QAAW,MAAM,OAAU;AAAA,EAC5C;AAAA,EACA,OAAO,IAA8D;AACnE,QAAI,CAAC,GAAI,QAAO;AAChB,WAAO,OAAO,KAAK,GAAG,SAAS,GAAG,OAAO,EAAE,SAAS,QAAQ;AAAA,EAC9D;AAAA,EACA,OACE,OACA,OAAU,UAC0D;AACpE,UAAM,QAAQ,OAAO,KAAK,OAAO,QAAQ,EAAE,SAAS,OAAO;AAC3D,QAAI,SAAS;AACX,aAAO,OAAO,KAAK;AACrB,QAAI,SAAS;AACX,aAAO,OAAO,KAAK;AACrB,WAAO;AAAA,EACT;AACF;AAEO,IAAM,mBAAmC,CAAC;AAE1C,SAAS,qBAAgC,OAAuC;AACrF,aAAO,sBAAQ,MAAM,OAAO,IAAI,IAAI,EAAE,MAAM,MAAM,OAAO,KAAK,IAAI;AACpE;AAEO,SAAS,iBAA4B,MAAsC;AAChF,aAAO,sBAAQ,KAAK,OAAO,IAAI,IAAI,EAAE,MAAM,KAAK,OAAO,KAAK,IAAI;AAClE;","names":[]}
1
+ {"version":3,"sources":["../src/response.ts"],"sourcesContent":["import { hasText } from '@shware/utils';\nimport { _default, coerce, int, maximum, minimum, object, optional, string } from 'zod/mini';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Empty = {};\nexport type EntityId = string | number;\nexport type Entity = { id: EntityId };\n\nexport type Response<T = never> = { data: T };\n\nexport type InitParams = { limit: number; parent?: string };\nexport type NextParams = { limit: number; parent?: string; next: string };\nexport type PrevParams = { limit: number; parent?: string; prev: string };\nexport type PageParams = { limit: number; prev?: string; next?: string };\nexport type ParentPageParams = { limit: number; parent: string; prev?: string; next?: string };\nexport type Page<T = never> = { data: T[]; paging: { next?: string; prev?: string } };\n\nexport function pageParamsSchema(max = 100, defaultLimit = 20) {\n return object({\n limit: _default(coerce.number().check(int(), minimum(1), maximum(max)), defaultLimit),\n prev: optional(string()),\n next: optional(string()),\n });\n}\n\nexport const Cursor = {\n of(\n prev: bigint | number | string | undefined,\n next: bigint | number | string | undefined\n ): Page['paging'] {\n return {\n prev: prev ? this.encode(prev) : undefined,\n next: next ? this.encode(next) : undefined,\n };\n },\n empty(): Page['paging'] {\n return { prev: undefined, next: undefined };\n },\n encode(id: bigint | number | string | undefined): string | undefined {\n if (!id) return undefined;\n return Buffer.from(id.toString(), 'utf-8').toString('base64');\n },\n decode<T extends 'bigint' | 'number' | 'string' = 'bigint'>(\n token: string,\n type: T = 'bigint' as T\n ): T extends 'bigint' ? bigint : T extends 'number' ? number : string {\n const value = Buffer.from(token, 'base64').toString('utf-8');\n if (type === 'bigint')\n return BigInt(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n if (type === 'number')\n return Number(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n return value as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n },\n};\n\nexport const initialPageParam: Page['paging'] = {};\n\nexport function getPreviousPageParam<T = never>(first: Page<T>): Page['paging'] | null {\n return hasText(first.paging.prev) ? { prev: first.paging.prev } : null;\n}\n\nexport function getNextPageParam<T = never>(last: Page<T>): Page['paging'] | null {\n return hasText(last.paging.next) ? { next: last.paging.next } : null;\n}\n\nexport type InfinitePageData<T> = {\n pages: Array<Page<T>>;\n pageParams: Array<Page['paging']>;\n};\n\nexport const pages = {\n flatten<T>(data: InfinitePageData<T>): T[] {\n return data.pages.flatMap((page) => page.data);\n },\n dedupe<T extends Entity>(data: InfinitePageData<T>): T[] {\n const seen = new Set<EntityId>();\n const result: T[] = [];\n for (const page of data.pages) {\n for (const item of page.data) {\n if (!seen.has(item.id)) {\n seen.add(item.id);\n result.push(item);\n }\n }\n }\n return result;\n },\n prepend<T>(item: T) {\n return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n if (!data) return data;\n const [first, ...rest] = data.pages;\n if (!first) return { ...data, pages: [{ data: [item], paging: {} }] };\n return { ...data, pages: [{ ...first, data: [item, ...first.data] }, ...rest] };\n };\n },\n append<T>(item: T) {\n return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n if (!data) return data;\n const pages = data.pages;\n const last = pages[pages.length - 1];\n if (!last) return { ...data, pages: [{ data: [item], paging: {} }] };\n return { ...data, pages: [...pages.slice(0, -1), { ...last, data: [...last.data, item] }] };\n };\n },\n remove<T>(predicate: (item: T) => boolean) {\n return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n if (!data) return data;\n return {\n ...data,\n pages: data.pages.map((page) => ({\n ...page,\n data: page.data.filter((item) => !predicate(item)),\n })),\n };\n };\n },\n update<T>(updater: T, predicate: (item: T) => boolean) {\n return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n if (!data) return data;\n return {\n ...data,\n pages: data.pages.map((page) => ({\n ...page,\n data: page.data.map((item) => (predicate(item) ? updater : item)),\n })),\n };\n };\n },\n updateById<T extends Entity>(updated: T) {\n return this.update<T>(updated, (item) => item.id === updated.id);\n },\n removeById<T extends Entity>(id: EntityId) {\n return this.remove<T>((item) => item.id === id);\n },\n};\n"],"mappings":"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","names":["pages"]}
@@ -55,5 +55,19 @@ declare const Cursor: {
55
55
  declare const initialPageParam: Page['paging'];
56
56
  declare function getPreviousPageParam<T = never>(first: Page<T>): Page['paging'] | null;
57
57
  declare function getNextPageParam<T = never>(last: Page<T>): Page['paging'] | null;
58
+ type InfinitePageData<T> = {
59
+ pages: Array<Page<T>>;
60
+ pageParams: Array<Page['paging']>;
61
+ };
62
+ declare const pages: {
63
+ flatten<T>(data: InfinitePageData<T>): T[];
64
+ dedupe<T extends Entity>(data: InfinitePageData<T>): T[];
65
+ prepend<T>(item: T): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
66
+ append<T>(item: T): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
67
+ remove<T>(predicate: (item: T) => boolean): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
68
+ update<T>(updater: T, predicate: (item: T) => boolean): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
69
+ updateById<T extends Entity>(updated: T): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
70
+ removeById<T extends Entity>(id: EntityId): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
71
+ };
58
72
 
59
- export { Cursor, type Empty, type Entity, type EntityId, type InitParams, type NextParams, type Page, type PageParams, type ParentPageParams, type PrevParams, type Response, getNextPageParam, getPreviousPageParam, initialPageParam, pageParamsSchema };
73
+ export { Cursor, type Empty, type Entity, type EntityId, type InfinitePageData, type InitParams, type NextParams, type Page, type PageParams, type ParentPageParams, type PrevParams, type Response, getNextPageParam, getPreviousPageParam, initialPageParam, pageParamsSchema, pages };
@@ -55,5 +55,19 @@ declare const Cursor: {
55
55
  declare const initialPageParam: Page['paging'];
56
56
  declare function getPreviousPageParam<T = never>(first: Page<T>): Page['paging'] | null;
57
57
  declare function getNextPageParam<T = never>(last: Page<T>): Page['paging'] | null;
58
+ type InfinitePageData<T> = {
59
+ pages: Array<Page<T>>;
60
+ pageParams: Array<Page['paging']>;
61
+ };
62
+ declare const pages: {
63
+ flatten<T>(data: InfinitePageData<T>): T[];
64
+ dedupe<T extends Entity>(data: InfinitePageData<T>): T[];
65
+ prepend<T>(item: T): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
66
+ append<T>(item: T): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
67
+ remove<T>(predicate: (item: T) => boolean): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
68
+ update<T>(updater: T, predicate: (item: T) => boolean): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
69
+ updateById<T extends Entity>(updated: T): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
70
+ removeById<T extends Entity>(id: EntityId): (data: InfinitePageData<T> | undefined) => InfinitePageData<T> | undefined;
71
+ };
58
72
 
59
- export { Cursor, type Empty, type Entity, type EntityId, type InitParams, type NextParams, type Page, type PageParams, type ParentPageParams, type PrevParams, type Response, getNextPageParam, getPreviousPageParam, initialPageParam, pageParamsSchema };
73
+ export { Cursor, type Empty, type Entity, type EntityId, type InfinitePageData, type InitParams, type NextParams, type Page, type PageParams, type ParentPageParams, type PrevParams, type Response, getNextPageParam, getPreviousPageParam, initialPageParam, pageParamsSchema, pages };
package/dist/response.mjs CHANGED
@@ -38,11 +38,77 @@ function getPreviousPageParam(first) {
38
38
  function getNextPageParam(last) {
39
39
  return hasText(last.paging.next) ? { next: last.paging.next } : null;
40
40
  }
41
+ var pages = {
42
+ flatten(data) {
43
+ return data.pages.flatMap((page) => page.data);
44
+ },
45
+ dedupe(data) {
46
+ const seen = /* @__PURE__ */ new Set();
47
+ const result = [];
48
+ for (const page of data.pages) {
49
+ for (const item of page.data) {
50
+ if (!seen.has(item.id)) {
51
+ seen.add(item.id);
52
+ result.push(item);
53
+ }
54
+ }
55
+ }
56
+ return result;
57
+ },
58
+ prepend(item) {
59
+ return (data) => {
60
+ if (!data) return data;
61
+ const [first, ...rest] = data.pages;
62
+ if (!first) return { ...data, pages: [{ data: [item], paging: {} }] };
63
+ return { ...data, pages: [{ ...first, data: [item, ...first.data] }, ...rest] };
64
+ };
65
+ },
66
+ append(item) {
67
+ return (data) => {
68
+ if (!data) return data;
69
+ const pages2 = data.pages;
70
+ const last = pages2[pages2.length - 1];
71
+ if (!last) return { ...data, pages: [{ data: [item], paging: {} }] };
72
+ return { ...data, pages: [...pages2.slice(0, -1), { ...last, data: [...last.data, item] }] };
73
+ };
74
+ },
75
+ remove(predicate) {
76
+ return (data) => {
77
+ if (!data) return data;
78
+ return {
79
+ ...data,
80
+ pages: data.pages.map((page) => ({
81
+ ...page,
82
+ data: page.data.filter((item) => !predicate(item))
83
+ }))
84
+ };
85
+ };
86
+ },
87
+ update(updater, predicate) {
88
+ return (data) => {
89
+ if (!data) return data;
90
+ return {
91
+ ...data,
92
+ pages: data.pages.map((page) => ({
93
+ ...page,
94
+ data: page.data.map((item) => predicate(item) ? updater : item)
95
+ }))
96
+ };
97
+ };
98
+ },
99
+ updateById(updated) {
100
+ return this.update(updated, (item) => item.id === updated.id);
101
+ },
102
+ removeById(id) {
103
+ return this.remove((item) => item.id === id);
104
+ }
105
+ };
41
106
  export {
42
107
  Cursor,
43
108
  getNextPageParam,
44
109
  getPreviousPageParam,
45
110
  initialPageParam,
46
- pageParamsSchema
111
+ pageParamsSchema,
112
+ pages
47
113
  };
48
114
  //# sourceMappingURL=response.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/response.ts"],"sourcesContent":["import { hasText } from '@shware/utils';\nimport { _default, coerce, int, maximum, minimum, object, optional, string } from 'zod/mini';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Empty = {};\nexport type EntityId = string | number;\nexport type Entity = { id: EntityId };\n\nexport type Response<T = never> = { data: T };\n\nexport type InitParams = { limit: number; parent?: string };\nexport type NextParams = { limit: number; parent?: string; next: string };\nexport type PrevParams = { limit: number; parent?: string; prev: string };\nexport type PageParams = { limit: number; prev?: string; next?: string };\nexport type ParentPageParams = { limit: number; parent: string; prev?: string; next?: string };\nexport type Page<T = never> = { data: T[]; paging: { next?: string; prev?: string } };\n\nexport function pageParamsSchema(max = 100, defaultLimit = 20) {\n return object({\n limit: _default(coerce.number().check(int(), minimum(1), maximum(max)), defaultLimit),\n prev: optional(string()),\n next: optional(string()),\n });\n}\n\nexport const Cursor = {\n of(\n prev: bigint | number | string | undefined,\n next: bigint | number | string | undefined\n ): Page['paging'] {\n return {\n prev: prev ? this.encode(prev) : undefined,\n next: next ? this.encode(next) : undefined,\n };\n },\n empty(): Page['paging'] {\n return { prev: undefined, next: undefined };\n },\n encode(id: bigint | number | string | undefined): string | undefined {\n if (!id) return undefined;\n return Buffer.from(id.toString(), 'utf-8').toString('base64');\n },\n decode<T extends 'bigint' | 'number' | 'string' = 'bigint'>(\n token: string,\n type: T = 'bigint' as T\n ): T extends 'bigint' ? bigint : T extends 'number' ? number : string {\n const value = Buffer.from(token, 'base64').toString('utf-8');\n if (type === 'bigint')\n return BigInt(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n if (type === 'number')\n return Number(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n return value as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n },\n};\n\nexport const initialPageParam: Page['paging'] = {};\n\nexport function getPreviousPageParam<T = never>(first: Page<T>): Page['paging'] | null {\n return hasText(first.paging.prev) ? { prev: first.paging.prev } : null;\n}\n\nexport function getNextPageParam<T = never>(last: Page<T>): Page['paging'] | null {\n return hasText(last.paging.next) ? { next: last.paging.next } : null;\n}\n"],"mappings":";AAAA,SAAS,eAAe;AACxB,SAAS,UAAU,QAAQ,KAAK,SAAS,SAAS,QAAQ,UAAU,cAAc;AAgB3E,SAAS,iBAAiB,MAAM,KAAK,eAAe,IAAI;AAC7D,SAAO,OAAO;AAAA,IACZ,OAAO,SAAS,OAAO,OAAO,EAAE,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,QAAQ,GAAG,CAAC,GAAG,YAAY;AAAA,IACpF,MAAM,SAAS,OAAO,CAAC;AAAA,IACvB,MAAM,SAAS,OAAO,CAAC;AAAA,EACzB,CAAC;AACH;AAEO,IAAM,SAAS;AAAA,EACpB,GACE,MACA,MACgB;AAChB,WAAO;AAAA,MACL,MAAM,OAAO,KAAK,OAAO,IAAI,IAAI;AAAA,MACjC,MAAM,OAAO,KAAK,OAAO,IAAI,IAAI;AAAA,IACnC;AAAA,EACF;AAAA,EACA,QAAwB;AACtB,WAAO,EAAE,MAAM,QAAW,MAAM,OAAU;AAAA,EAC5C;AAAA,EACA,OAAO,IAA8D;AACnE,QAAI,CAAC,GAAI,QAAO;AAChB,WAAO,OAAO,KAAK,GAAG,SAAS,GAAG,OAAO,EAAE,SAAS,QAAQ;AAAA,EAC9D;AAAA,EACA,OACE,OACA,OAAU,UAC0D;AACpE,UAAM,QAAQ,OAAO,KAAK,OAAO,QAAQ,EAAE,SAAS,OAAO;AAC3D,QAAI,SAAS;AACX,aAAO,OAAO,KAAK;AACrB,QAAI,SAAS;AACX,aAAO,OAAO,KAAK;AACrB,WAAO;AAAA,EACT;AACF;AAEO,IAAM,mBAAmC,CAAC;AAE1C,SAAS,qBAAgC,OAAuC;AACrF,SAAO,QAAQ,MAAM,OAAO,IAAI,IAAI,EAAE,MAAM,MAAM,OAAO,KAAK,IAAI;AACpE;AAEO,SAAS,iBAA4B,MAAsC;AAChF,SAAO,QAAQ,KAAK,OAAO,IAAI,IAAI,EAAE,MAAM,KAAK,OAAO,KAAK,IAAI;AAClE;","names":[]}
1
+ {"version":3,"sources":["../src/response.ts"],"sourcesContent":["import { hasText } from '@shware/utils';\nimport { _default, coerce, int, maximum, minimum, object, optional, string } from 'zod/mini';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type Empty = {};\nexport type EntityId = string | number;\nexport type Entity = { id: EntityId };\n\nexport type Response<T = never> = { data: T };\n\nexport type InitParams = { limit: number; parent?: string };\nexport type NextParams = { limit: number; parent?: string; next: string };\nexport type PrevParams = { limit: number; parent?: string; prev: string };\nexport type PageParams = { limit: number; prev?: string; next?: string };\nexport type ParentPageParams = { limit: number; parent: string; prev?: string; next?: string };\nexport type Page<T = never> = { data: T[]; paging: { next?: string; prev?: string } };\n\nexport function pageParamsSchema(max = 100, defaultLimit = 20) {\n return object({\n limit: _default(coerce.number().check(int(), minimum(1), maximum(max)), defaultLimit),\n prev: optional(string()),\n next: optional(string()),\n });\n}\n\nexport const Cursor = {\n of(\n prev: bigint | number | string | undefined,\n next: bigint | number | string | undefined\n ): Page['paging'] {\n return {\n prev: prev ? this.encode(prev) : undefined,\n next: next ? this.encode(next) : undefined,\n };\n },\n empty(): Page['paging'] {\n return { prev: undefined, next: undefined };\n },\n encode(id: bigint | number | string | undefined): string | undefined {\n if (!id) return undefined;\n return Buffer.from(id.toString(), 'utf-8').toString('base64');\n },\n decode<T extends 'bigint' | 'number' | 'string' = 'bigint'>(\n token: string,\n type: T = 'bigint' as T\n ): T extends 'bigint' ? bigint : T extends 'number' ? number : string {\n const value = Buffer.from(token, 'base64').toString('utf-8');\n if (type === 'bigint')\n return BigInt(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n if (type === 'number')\n return Number(value) as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n return value as T extends 'bigint' ? bigint : T extends 'number' ? number : string;\n },\n};\n\nexport const initialPageParam: Page['paging'] = {};\n\nexport function getPreviousPageParam<T = never>(first: Page<T>): Page['paging'] | null {\n return hasText(first.paging.prev) ? { prev: first.paging.prev } : null;\n}\n\nexport function getNextPageParam<T = never>(last: Page<T>): Page['paging'] | null {\n return hasText(last.paging.next) ? { next: last.paging.next } : null;\n}\n\nexport type InfinitePageData<T> = {\n pages: Array<Page<T>>;\n pageParams: Array<Page['paging']>;\n};\n\nexport const pages = {\n flatten<T>(data: InfinitePageData<T>): T[] {\n return data.pages.flatMap((page) => page.data);\n },\n dedupe<T extends Entity>(data: InfinitePageData<T>): T[] {\n const seen = new Set<EntityId>();\n const result: T[] = [];\n for (const page of data.pages) {\n for (const item of page.data) {\n if (!seen.has(item.id)) {\n seen.add(item.id);\n result.push(item);\n }\n }\n }\n return result;\n },\n prepend<T>(item: T) {\n return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n if (!data) return data;\n const [first, ...rest] = data.pages;\n if (!first) return { ...data, pages: [{ data: [item], paging: {} }] };\n return { ...data, pages: [{ ...first, data: [item, ...first.data] }, ...rest] };\n };\n },\n append<T>(item: T) {\n return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n if (!data) return data;\n const pages = data.pages;\n const last = pages[pages.length - 1];\n if (!last) return { ...data, pages: [{ data: [item], paging: {} }] };\n return { ...data, pages: [...pages.slice(0, -1), { ...last, data: [...last.data, item] }] };\n };\n },\n remove<T>(predicate: (item: T) => boolean) {\n return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n if (!data) return data;\n return {\n ...data,\n pages: data.pages.map((page) => ({\n ...page,\n data: page.data.filter((item) => !predicate(item)),\n })),\n };\n };\n },\n update<T>(updater: T, predicate: (item: T) => boolean) {\n return (data: InfinitePageData<T> | undefined): InfinitePageData<T> | undefined => {\n if (!data) return data;\n return {\n ...data,\n pages: data.pages.map((page) => ({\n ...page,\n data: page.data.map((item) => (predicate(item) ? updater : item)),\n })),\n };\n };\n },\n updateById<T extends Entity>(updated: T) {\n return this.update<T>(updated, (item) => item.id === updated.id);\n },\n removeById<T extends Entity>(id: EntityId) {\n return this.remove<T>((item) => item.id === id);\n },\n};\n"],"mappings":"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","names":["pages"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shware/http",
3
- "version": "2.4.2",
3
+ "version": "2.4.3",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",