ag-grid-url-sync 0.1.1 → 0.2.1

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.
Files changed (42) hide show
  1. package/README.md +407 -43
  2. package/dist/{ag-grid-url-sync.js → core/ag-grid-url-sync.js} +4 -2
  3. package/dist/core/ag-grid-url-sync.js.map +1 -0
  4. package/dist/core/grid-integration.d.ts +9 -0
  5. package/dist/core/grid-integration.js +66 -0
  6. package/dist/core/grid-integration.js.map +1 -0
  7. package/dist/core/index.d.ts +6 -0
  8. package/dist/core/index.js +11 -0
  9. package/dist/core/index.js.map +1 -0
  10. package/dist/core/types.d.ts +112 -0
  11. package/dist/core/types.js +79 -0
  12. package/dist/core/types.js.map +1 -0
  13. package/dist/core/url-generator.d.ts +9 -0
  14. package/dist/core/url-generator.js +42 -0
  15. package/dist/core/url-generator.js.map +1 -0
  16. package/dist/core/url-parser.d.ts +9 -0
  17. package/dist/core/url-parser.js +85 -0
  18. package/dist/core/url-parser.js.map +1 -0
  19. package/dist/core/validation.d.ts +18 -0
  20. package/dist/core/validation.js +28 -0
  21. package/dist/core/validation.js.map +1 -0
  22. package/dist/index.d.ts +6 -3
  23. package/dist/index.js +11 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/react/index.d.ts +3 -0
  26. package/dist/react/index.js +2 -0
  27. package/dist/react/index.js.map +1 -0
  28. package/dist/react/types.d.ts +64 -0
  29. package/dist/react/types.js +2 -0
  30. package/dist/react/types.js.map +1 -0
  31. package/dist/react/use-ag-grid-url-sync.d.ts +10 -0
  32. package/dist/react/use-ag-grid-url-sync.js +215 -0
  33. package/dist/react/use-ag-grid-url-sync.js.map +1 -0
  34. package/package.json +95 -6
  35. package/dist/ag-grid-url-sync.js.map +0 -1
  36. package/dist/types.d.ts +0 -69
  37. package/dist/types.js +0 -31
  38. package/dist/types.js.map +0 -1
  39. package/dist/utils.d.ts +0 -36
  40. package/dist/utils.js +0 -188
  41. package/dist/utils.js.map +0 -1
  42. /package/dist/{ag-grid-url-sync.d.ts → core/ag-grid-url-sync.d.ts} +0 -0
@@ -0,0 +1,112 @@
1
+ import type { GridApi as AGGridApi } from 'ag-grid-community';
2
+ /**
3
+ * Configuration options for AG Grid URL Sync
4
+ */
5
+ export interface AGGridUrlSyncConfig {
6
+ /**
7
+ * Prefix for URL parameters. Default: 'f_'
8
+ */
9
+ paramPrefix?: string;
10
+ /**
11
+ * Maximum length for filter values. Default: 200
12
+ */
13
+ maxValueLength?: number;
14
+ /**
15
+ * Optional error handler for parsing errors
16
+ */
17
+ onParseError?: (error: Error) => void;
18
+ }
19
+ /**
20
+ * Supported filter operations
21
+ */
22
+ export type FilterOperation = 'contains' | 'eq' | 'notContains' | 'notEqual' | 'startsWith' | 'endsWith' | 'blank' | 'notBlank';
23
+ /**
24
+ * Filter state for a single column
25
+ */
26
+ export interface ColumnFilter {
27
+ filterType: 'text';
28
+ type: FilterOperation;
29
+ filter: string;
30
+ }
31
+ /**
32
+ * Complete filter state mapping
33
+ */
34
+ export interface FilterState {
35
+ [columnId: string]: ColumnFilter;
36
+ }
37
+ /**
38
+ * Internal configuration with defaults
39
+ */
40
+ export interface InternalConfig extends Required<AGGridUrlSyncConfig> {
41
+ gridApi: AGGridApi;
42
+ }
43
+ /**
44
+ * Error types for URL sync operations
45
+ */
46
+ export declare class URLSyncError extends Error {
47
+ constructor(message: string);
48
+ }
49
+ export declare class InvalidFilterError extends URLSyncError {
50
+ constructor(message: string);
51
+ }
52
+ export declare class InvalidURLError extends URLSyncError {
53
+ constructor(message: string);
54
+ }
55
+ export type ParsedFilterParam = {
56
+ columnName: string;
57
+ operation: FilterOperation;
58
+ value: string;
59
+ action: 'apply' | 'remove';
60
+ };
61
+ export type GridApi = AGGridApi;
62
+ /**
63
+ * Operation Mapping Strategy:
64
+ *
65
+ * We use three different naming conventions for better user experience:
66
+ *
67
+ * 1. URL Parameters: Short, clean names for URLs (e.g., 'eq', 'neq')
68
+ * 2. Internal Types: Consistent naming for our FilterOperation type
69
+ * 3. AG Grid Operations: Exact names expected by AG Grid API (e.g., 'equals', 'notEqual')
70
+ *
71
+ * This approach keeps URLs readable while maintaining compatibility with AG Grid.
72
+ */
73
+ export declare const OPERATION_MAP: {
74
+ readonly contains: "contains";
75
+ readonly eq: "eq";
76
+ readonly notContains: "notContains";
77
+ readonly neq: "notEqual";
78
+ readonly startsWith: "startsWith";
79
+ readonly endsWith: "endsWith";
80
+ readonly blank: "blank";
81
+ readonly notBlank: "notBlank";
82
+ };
83
+ export declare const INTERNAL_TO_URL_OPERATION_MAP: {
84
+ readonly contains: "contains";
85
+ readonly eq: "eq";
86
+ readonly notContains: "notContains";
87
+ readonly notEqual: "neq";
88
+ readonly startsWith: "startsWith";
89
+ readonly endsWith: "endsWith";
90
+ readonly blank: "blank";
91
+ readonly notBlank: "notBlank";
92
+ };
93
+ export declare const AG_GRID_OPERATION_NAMES: {
94
+ readonly contains: "contains";
95
+ readonly eq: "equals";
96
+ readonly notContains: "notContains";
97
+ readonly notEqual: "notEqual";
98
+ readonly startsWith: "startsWith";
99
+ readonly endsWith: "endsWith";
100
+ readonly blank: "blank";
101
+ readonly notBlank: "notBlank";
102
+ };
103
+ export declare const REVERSE_AG_GRID_OPERATION_NAMES: {
104
+ readonly contains: "contains";
105
+ readonly equals: "eq";
106
+ readonly notContains: "notContains";
107
+ readonly notEqual: "notEqual";
108
+ readonly startsWith: "startsWith";
109
+ readonly endsWith: "endsWith";
110
+ readonly blank: "blank";
111
+ readonly notBlank: "notBlank";
112
+ };
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Error types for URL sync operations
3
+ */
4
+ export class URLSyncError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = 'URLSyncError';
8
+ }
9
+ }
10
+ export class InvalidFilterError extends URLSyncError {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = 'InvalidFilterError';
14
+ }
15
+ }
16
+ export class InvalidURLError extends URLSyncError {
17
+ constructor(message) {
18
+ super(message);
19
+ this.name = 'InvalidURLError';
20
+ }
21
+ }
22
+ /**
23
+ * Operation Mapping Strategy:
24
+ *
25
+ * We use three different naming conventions for better user experience:
26
+ *
27
+ * 1. URL Parameters: Short, clean names for URLs (e.g., 'eq', 'neq')
28
+ * 2. Internal Types: Consistent naming for our FilterOperation type
29
+ * 3. AG Grid Operations: Exact names expected by AG Grid API (e.g., 'equals', 'notEqual')
30
+ *
31
+ * This approach keeps URLs readable while maintaining compatibility with AG Grid.
32
+ */
33
+ // URL parameter names to internal operation types
34
+ // Uses short names for cleaner URLs: 'eq' instead of 'equals', 'neq' instead of 'notEqual'
35
+ export const OPERATION_MAP = {
36
+ contains: 'contains',
37
+ eq: 'eq', // Short form for URL brevity
38
+ notContains: 'notContains',
39
+ neq: 'notEqual', // Short form: 'neq' -> 'notEqual'
40
+ startsWith: 'startsWith',
41
+ endsWith: 'endsWith',
42
+ blank: 'blank',
43
+ notBlank: 'notBlank'
44
+ };
45
+ // Internal operation types to URL parameter names
46
+ export const INTERNAL_TO_URL_OPERATION_MAP = {
47
+ contains: 'contains',
48
+ eq: 'eq',
49
+ notContains: 'notContains',
50
+ notEqual: 'neq', // Internal 'notEqual' -> URL 'neq'
51
+ startsWith: 'startsWith',
52
+ endsWith: 'endsWith',
53
+ blank: 'blank',
54
+ notBlank: 'notBlank'
55
+ };
56
+ // Internal operation types to AG Grid operation names
57
+ // AG Grid expects 'equals' not 'eq', 'notEqual' not 'neq'
58
+ export const AG_GRID_OPERATION_NAMES = {
59
+ contains: 'contains',
60
+ eq: 'equals', // Internal 'eq' -> AG Grid 'equals'
61
+ notContains: 'notContains',
62
+ notEqual: 'notEqual',
63
+ startsWith: 'startsWith',
64
+ endsWith: 'endsWith',
65
+ blank: 'blank',
66
+ notBlank: 'notBlank'
67
+ };
68
+ // AG Grid operation names to internal operation types (reverse mapping)
69
+ export const REVERSE_AG_GRID_OPERATION_NAMES = {
70
+ contains: 'contains',
71
+ equals: 'eq', // AG Grid 'equals' -> Internal 'eq'
72
+ notContains: 'notContains',
73
+ notEqual: 'notEqual',
74
+ startsWith: 'startsWith',
75
+ endsWith: 'endsWith',
76
+ blank: 'blank',
77
+ notBlank: 'notBlank'
78
+ };
79
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AA0DA;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,cAAc,CAAA;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IAClD,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;IAClC,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;IAC/B,CAAC;CACF;AAYD;;;;;;;;;;GAUG;AAEH,kDAAkD;AAClD,2FAA2F;AAC3F,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,QAAQ,EAAE,UAAU;IACpB,EAAE,EAAE,IAAI,EAAE,6BAA6B;IACvC,WAAW,EAAE,aAAa;IAC1B,GAAG,EAAE,UAAU,EAAE,kCAAkC;IACnD,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;CACZ,CAAA;AAEV,kDAAkD;AAClD,MAAM,CAAC,MAAM,6BAA6B,GAAG;IAC3C,QAAQ,EAAE,UAAU;IACpB,EAAE,EAAE,IAAI;IACR,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,KAAK,EAAE,mCAAmC;IACpD,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;CACZ,CAAA;AAEV,sDAAsD;AACtD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,QAAQ,EAAE,UAAU;IACpB,EAAE,EAAE,QAAQ,EAAE,oCAAoC;IAClD,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;IACpB,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;CACZ,CAAA;AAEV,wEAAwE;AACxE,MAAM,CAAC,MAAM,+BAA+B,GAAG;IAC7C,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,IAAI,EAAE,oCAAoC;IAClD,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;IACpB,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;CACZ,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { FilterState, InternalConfig } from './types.js';
2
+ /**
3
+ * Converts a filter state object into URL search parameters
4
+ */
5
+ export declare function serializeFilters(filterState: FilterState, config: InternalConfig): URLSearchParams;
6
+ /**
7
+ * Generates a URL with the current filter state
8
+ */
9
+ export declare function generateUrl(baseUrl: string, filterState: FilterState, config: InternalConfig): string;
@@ -0,0 +1,42 @@
1
+ import { validateFilterValue } from './validation.js';
2
+ import { INTERNAL_TO_URL_OPERATION_MAP } from './types.js';
3
+ /**
4
+ * Converts a filter state object into URL search parameters
5
+ */
6
+ export function serializeFilters(filterState, config) {
7
+ const params = new URLSearchParams();
8
+ for (const [column, filter] of Object.entries(filterState)) {
9
+ if (filter.filterType !== 'text')
10
+ continue;
11
+ const operation = INTERNAL_TO_URL_OPERATION_MAP[filter.type];
12
+ if (!operation)
13
+ continue;
14
+ const paramName = `${config.paramPrefix}${column}_${operation}`;
15
+ // Special handling for blank operations
16
+ if (filter.type === 'blank' || filter.type === 'notBlank') {
17
+ params.append(paramName, 'true');
18
+ }
19
+ else {
20
+ const value = validateFilterValue(filter.filter, config, filter.type);
21
+ // URLSearchParams already handles encoding, so don't double-encode
22
+ params.append(paramName, value);
23
+ }
24
+ }
25
+ return params;
26
+ }
27
+ /**
28
+ * Generates a URL with the current filter state
29
+ */
30
+ export function generateUrl(baseUrl, filterState, config) {
31
+ const url = new URL(baseUrl);
32
+ const filterParams = serializeFilters(filterState, config);
33
+ // Preserve existing non-filter parameters
34
+ for (const [key, value] of url.searchParams.entries()) {
35
+ if (!key.startsWith(config.paramPrefix)) {
36
+ filterParams.append(key, value);
37
+ }
38
+ }
39
+ url.search = filterParams.toString();
40
+ return url.toString();
41
+ }
42
+ //# sourceMappingURL=url-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-generator.js","sourceRoot":"","sources":["../../src/core/url-generator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAA;AAE1D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,WAAwB,EACxB,MAAsB;IAEtB,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAA;IAEpC,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QAC3D,IAAI,MAAM,CAAC,UAAU,KAAK,MAAM;YAAE,SAAQ;QAE1C,MAAM,SAAS,GACb,6BAA6B,CAC3B,MAAM,CAAC,IAAkD,CAC1D,CAAA;QACH,IAAI,CAAC,SAAS;YAAE,SAAQ;QAExB,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,WAAW,GAAG,MAAM,IAAI,SAAS,EAAE,CAAA;QAE/D,wCAAwC;QACxC,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,mBAAmB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;YACrE,mEAAmE;YACnE,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,OAAe,EACf,WAAwB,EACxB,MAAsB;IAEtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAA;IAC5B,MAAM,YAAY,GAAG,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAE1D,0CAA0C;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;QACtD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YACxC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IAED,GAAG,CAAC,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAA;IACpC,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAA;AACvB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { FilterState, ColumnFilter, InternalConfig } from './types.js';
2
+ /**
3
+ * Parses a URL parameter into a column filter
4
+ */
5
+ export declare function parseFilterParam(param: string, value: string, expectedPrefix?: string): ColumnFilter;
6
+ /**
7
+ * Converts URL search params into a filter state object
8
+ */
9
+ export declare function parseUrlFilters(url: string, config: InternalConfig): FilterState;
@@ -0,0 +1,85 @@
1
+ import { InvalidFilterError, InvalidURLError, OPERATION_MAP } from './types.js';
2
+ import { validateFilterValue, DEFAULT_CONFIG } from './validation.js';
3
+ /**
4
+ * Extracts column name and operation from a filter parameter
5
+ */
6
+ function extractColumnAndOperation(param, expectedPrefix) {
7
+ const ensureTrailingUnderscore = (prefix) => prefix.endsWith('_') ? prefix : prefix + '_';
8
+ const sanitizedPrefix = expectedPrefix
9
+ ? ensureTrailingUnderscore(expectedPrefix)
10
+ : ensureTrailingUnderscore(DEFAULT_CONFIG.paramPrefix);
11
+ const prefixToCheck = sanitizedPrefix.slice(0, -1);
12
+ if (!param.startsWith(prefixToCheck + '_')) {
13
+ throw new InvalidFilterError(`Invalid filter prefix in parameter: ${param}`);
14
+ }
15
+ // Remove prefix and find the last underscore to separate column from operation
16
+ const withoutPrefix = param.substring(prefixToCheck.length + 1);
17
+ const lastUnderscoreIndex = withoutPrefix.lastIndexOf('_');
18
+ if (lastUnderscoreIndex === -1) {
19
+ throw new InvalidFilterError(`Invalid filter parameter format: ${param}`);
20
+ }
21
+ const column = withoutPrefix.substring(0, lastUnderscoreIndex);
22
+ const operation = withoutPrefix.substring(lastUnderscoreIndex + 1);
23
+ if (!column.trim()) {
24
+ throw new InvalidFilterError(`Empty column name in parameter: ${param}`);
25
+ }
26
+ return { column, operation };
27
+ }
28
+ /**
29
+ * Parses a URL parameter into a column filter
30
+ */
31
+ export function parseFilterParam(param, value, expectedPrefix) {
32
+ const { operation } = extractColumnAndOperation(param, expectedPrefix);
33
+ const filterOp = OPERATION_MAP[operation];
34
+ if (!filterOp) {
35
+ throw new InvalidFilterError(`Unsupported filter operation: ${operation}`);
36
+ }
37
+ // Special handling for blank operations - they don't use the value
38
+ if (filterOp === 'blank' || filterOp === 'notBlank') {
39
+ return {
40
+ filterType: 'text',
41
+ type: filterOp,
42
+ filter: '' // Blank operations don't use the value
43
+ };
44
+ }
45
+ return {
46
+ filterType: 'text',
47
+ type: filterOp,
48
+ filter: value || ''
49
+ };
50
+ }
51
+ /**
52
+ * Converts URL search params into a filter state object
53
+ */
54
+ export function parseUrlFilters(url, config) {
55
+ try {
56
+ const urlObj = new URL(url);
57
+ const filterState = {};
58
+ for (const [param, value] of urlObj.searchParams.entries()) {
59
+ if (!param.startsWith(config.paramPrefix))
60
+ continue;
61
+ try {
62
+ // Extract column name and parse the filter parameter
63
+ const { column: columnName } = extractColumnAndOperation(param, config.paramPrefix);
64
+ const filterParam = parseFilterParam(param, value, config.paramPrefix);
65
+ const validatedValue = validateFilterValue(value, config, filterParam.type);
66
+ filterState[columnName] = {
67
+ ...filterParam,
68
+ filter: validatedValue
69
+ };
70
+ }
71
+ catch (err) {
72
+ if (config.onParseError) {
73
+ config.onParseError(err);
74
+ }
75
+ // Skip invalid filters but continue processing
76
+ continue;
77
+ }
78
+ }
79
+ return filterState;
80
+ }
81
+ catch (err) {
82
+ throw new InvalidURLError(`Failed to parse URL: ${err.message}`);
83
+ }
84
+ }
85
+ //# sourceMappingURL=url-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-parser.js","sourceRoot":"","sources":["../../src/core/url-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { InternalConfig, FilterOperation } from './types.js';
2
+ /**
3
+ * Default configuration values
4
+ */
5
+ export declare const DEFAULT_CONFIG: {
6
+ readonly paramPrefix: "f_";
7
+ readonly maxValueLength: 200;
8
+ };
9
+ /**
10
+ * Validates a filter value against configuration constraints
11
+ *
12
+ * @param value - The filter value to validate
13
+ * @param config - Internal configuration with validation rules
14
+ * @param operation - Optional filter operation type. Blank operations (blank/notBlank) bypass value validation
15
+ * @returns The validated filter value (empty string for blank operations)
16
+ * @throws InvalidFilterError if value exceeds maximum length
17
+ */
18
+ export declare function validateFilterValue(value: string, config: InternalConfig, operation?: FilterOperation): string;
@@ -0,0 +1,28 @@
1
+ import { InvalidFilterError } from './types.js';
2
+ /**
3
+ * Default configuration values
4
+ */
5
+ export const DEFAULT_CONFIG = {
6
+ paramPrefix: 'f_',
7
+ maxValueLength: 200
8
+ };
9
+ /**
10
+ * Validates a filter value against configuration constraints
11
+ *
12
+ * @param value - The filter value to validate
13
+ * @param config - Internal configuration with validation rules
14
+ * @param operation - Optional filter operation type. Blank operations (blank/notBlank) bypass value validation
15
+ * @returns The validated filter value (empty string for blank operations)
16
+ * @throws InvalidFilterError if value exceeds maximum length
17
+ */
18
+ export function validateFilterValue(value, config, operation) {
19
+ // Blank operations don't require value validation
20
+ if (operation === 'blank' || operation === 'notBlank') {
21
+ return '';
22
+ }
23
+ if (value.length > config.maxValueLength) {
24
+ throw new InvalidFilterError(`Filter value exceeds maximum length of ${config.maxValueLength} characters`);
25
+ }
26
+ return value;
27
+ }
28
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE/C;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,GAAG;CACX,CAAA;AAEV;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,MAAsB,EACtB,SAA2B;IAE3B,kDAAkD;IAClD,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QACtD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;QACzC,MAAM,IAAI,kBAAkB,CAC1B,0CAA0C,MAAM,CAAC,cAAc,aAAa,CAC7E,CAAA;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
- export { AGGridUrlSync, createUrlSync } from './ag-grid-url-sync.js';
2
- export * from './types.js';
3
- export { parseUrlFilters, serializeFilters, generateUrl, getFilterModel, applyFilterModel, validateFilterValue, parseFilterParam, DEFAULT_CONFIG } from './utils.js';
1
+ export { AGGridUrlSync, createUrlSync } from './core/ag-grid-url-sync.js';
2
+ export * from './core/types.js';
3
+ export { validateFilterValue, DEFAULT_CONFIG } from './core/validation.js';
4
+ export { parseUrlFilters, parseFilterParam } from './core/url-parser.js';
5
+ export { serializeFilters, generateUrl } from './core/url-generator.js';
6
+ export { getFilterModel, applyFilterModel } from './core/grid-integration.js';
package/dist/index.js CHANGED
@@ -1,4 +1,12 @@
1
- export { AGGridUrlSync, createUrlSync } from './ag-grid-url-sync.js';
2
- export * from './types.js';
3
- export { parseUrlFilters, serializeFilters, generateUrl, getFilterModel, applyFilterModel, validateFilterValue, parseFilterParam, DEFAULT_CONFIG } from './utils.js';
1
+ // Export core functionality (vanilla JS)
2
+ export { AGGridUrlSync, createUrlSync } from './core/ag-grid-url-sync.js';
3
+ export * from './core/types.js';
4
+ // Validation utilities
5
+ export { validateFilterValue, DEFAULT_CONFIG } from './core/validation.js';
6
+ // URL parsing utilities
7
+ export { parseUrlFilters, parseFilterParam } from './core/url-parser.js';
8
+ // URL generation utilities
9
+ export { serializeFilters, generateUrl } from './core/url-generator.js';
10
+ // AG Grid integration utilities
11
+ export { getFilterModel, applyFilterModel } from './core/grid-integration.js';
4
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAEpE,cAAc,YAAY,CAAA;AAE1B,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACf,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAEzE,cAAc,iBAAiB,CAAA;AAE/B,uBAAuB;AACvB,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1E,wBAAwB;AACxB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAExE,2BAA2B;AAC3B,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAEvE,gCAAgC;AAChC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { useAGGridUrlSync } from './use-ag-grid-url-sync.js';
2
+ export type { UseAGGridUrlSyncOptions, UseAGGridUrlSyncReturn } from './types.js';
3
+ export type { FilterState, ColumnFilter, FilterOperation, AGGridUrlSyncConfig, GridApi } from '../core/types.js';
@@ -0,0 +1,2 @@
1
+ export { useAGGridUrlSync } from './use-ag-grid-url-sync.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA"}
@@ -0,0 +1,64 @@
1
+ import type { AGGridUrlSyncConfig, FilterState } from '../core/types.js';
2
+ /**
3
+ * Configuration options for the React hook
4
+ */
5
+ export interface UseAGGridUrlSyncOptions extends AGGridUrlSyncConfig {
6
+ /**
7
+ * Automatically apply URL filters when the component mounts and grid API becomes ready
8
+ * Default: false
9
+ */
10
+ autoApplyOnMount?: boolean;
11
+ /**
12
+ * Whether the hook should be enabled when the grid API is ready
13
+ * Default: true
14
+ */
15
+ enabledWhenReady?: boolean;
16
+ }
17
+ /**
18
+ * Return type for the useAGGridUrlSync hook
19
+ */
20
+ export interface UseAGGridUrlSyncReturn {
21
+ /**
22
+ * Generate a URL with current filter state
23
+ * @param baseUrl - Optional base URL (defaults to current URL)
24
+ * @returns URL string with filter parameters
25
+ */
26
+ shareUrl: (baseUrl?: string) => string;
27
+ /**
28
+ * Get current filter state as query parameters string
29
+ * @returns Query parameter string
30
+ */
31
+ getQueryParams: () => string;
32
+ /**
33
+ * Apply filters from a URL to the grid
34
+ * @param url - Optional URL to parse (defaults to current URL)
35
+ */
36
+ applyUrlFilters: (url?: string) => void;
37
+ /**
38
+ * Clear all text filters from the grid
39
+ */
40
+ clearFilters: () => void;
41
+ /**
42
+ * Whether the grid API is available and hook is ready
43
+ */
44
+ isReady: boolean;
45
+ /**
46
+ * Current generated URL with filters
47
+ */
48
+ currentUrl: string;
49
+ /**
50
+ * Whether the grid has any active text filters
51
+ */
52
+ hasFilters: boolean;
53
+ /**
54
+ * Parse filters from a URL without applying them
55
+ * @param url - URL to parse
56
+ * @returns Parsed filter state
57
+ */
58
+ parseUrlFilters: (url: string) => FilterState;
59
+ /**
60
+ * Apply a filter state object to the grid
61
+ * @param filters - Filter state to apply
62
+ */
63
+ applyFilters: (filters: FilterState) => void;
64
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/react/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import type { GridApi } from 'ag-grid-community';
2
+ import type { UseAGGridUrlSyncOptions, UseAGGridUrlSyncReturn } from './types.js';
3
+ /**
4
+ * React hook for AG Grid URL synchronization
5
+ *
6
+ * @param gridApi - AG Grid API instance (can be null during initialization)
7
+ * @param options - Configuration options for the hook
8
+ * @returns Hook API for URL synchronization
9
+ */
10
+ export declare function useAGGridUrlSync(gridApi: GridApi | null, options?: UseAGGridUrlSyncOptions): UseAGGridUrlSyncReturn;