@electrolux-oss/plugin-infrawallet 1.1.0-20251122142002-7ac6f9a → 1.1.0-20251202133007-1005ef9

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.
@@ -59,6 +59,14 @@ const quoteLuceneValue = (value) => {
59
59
  }
60
60
  return value;
61
61
  };
62
+ const quoteTag = (provider, key, value) => {
63
+ const specialChars = /[/()[\]{}\s:]/;
64
+ const tag = `${provider}.${key}=${value}`;
65
+ if (specialChars.test(key)) {
66
+ return `tag:"${tag}"`;
67
+ }
68
+ return `tag:${tag}`;
69
+ };
62
70
  const filtersAndTagsToLucene = (filters, tags) => {
63
71
  const queryParts = [];
64
72
  for (const field of Object.keys(filters)) {
@@ -74,7 +82,7 @@ const filtersAndTagsToLucene = (filters, tags) => {
74
82
  }
75
83
  for (const tag of tags) {
76
84
  if (tag.provider && tag.key && tag.value) {
77
- queryParts.push(`tag:${tag.provider}.${tag.key}=${tag.value}`);
85
+ queryParts.push(quoteTag(tag.provider, tag.key, tag.value));
78
86
  }
79
87
  }
80
88
  return queryParts.join(" AND ");
@@ -1 +1 @@
1
- {"version":3,"file":"useInfraWalletLuceneParams.esm.js","sources":["../../src/hooks/useInfraWalletLuceneParams.ts"],"sourcesContent":["import { format, parse, startOfMonth } from 'date-fns';\nimport * as lucene from 'lucene';\nimport { useCallback, useEffect, useRef } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Filters, Tag } from '../api/types';\nimport { MonthRange } from '../components/types';\n\n/**\n * Parse tag value into Tag object\n * Supports two formats:\n * 1. provider.key=value (preferred)\n * 2. provider:key:value (fallback)\n */\nconst parseTag = (tagValue: string): Tag | null => {\n // Try provider.key=value format first\n if (tagValue.includes('.') && tagValue.includes('=')) {\n const [providerKey, value] = tagValue.split('=');\n const [provider, key] = providerKey.split('.');\n if (provider && key && value) {\n return { provider, key, value };\n }\n }\n\n // Fallback to provider:key:value format\n if (tagValue.includes(':')) {\n const tagParts = tagValue.split(':');\n if (tagParts.length >= 3) {\n const provider = tagParts[0];\n const key = tagParts[1];\n const value = tagParts.slice(2).join(':'); // In case value contains colons\n return { provider, key, value };\n }\n }\n\n return null;\n};\n\n/**\n * Add a filter value to the filters object, avoiding duplicates\n */\nconst addFilterValue = (filters: Filters, field: string, value: string): void => {\n if (!filters[field]) {\n filters[field] = [];\n }\n if (!filters[field].includes(value)) {\n filters[field].push(value);\n }\n};\n\n/**\n * Convert Lucene AST to Filters and Tags\n */\nconst astToFiltersAndTags = (ast: any): { filters: Filters; tags: Tag[] } => {\n const filters: Filters = {};\n const tags: Tag[] = [];\n\n const traverseAST = (node: any): void => {\n if (!node) return;\n\n // Process field:value pairs\n if (node.field && node.term) {\n if (node.field === 'tag') {\n const tag = parseTag(node.term);\n if (tag) {\n tags.push(tag);\n }\n } else {\n addFilterValue(filters, node.field, node.term);\n }\n }\n\n // Recursively process left and right nodes\n if (node.left) traverseAST(node.left);\n if (node.right) traverseAST(node.right);\n };\n\n traverseAST(ast);\n return { filters, tags };\n};\n\n/**\n * Escape and quote a value for Lucene query if it contains special characters\n */\nconst quoteLuceneValue = (value: string): string => {\n // Check if value contains special Lucene characters that require quoting\n const specialChars = /[/()[\\]{}\\s:]/;\n if (specialChars.test(value)) {\n // Escape any quotes in the value and wrap in quotes\n const escapedQuote = String.raw`\\\"`;\n return `\"${value.replaceAll('\"', escapedQuote)}\"`;\n }\n return value;\n};\n\n/**\n * Convert Filters and Tags to Lucene query string\n */\nconst filtersAndTagsToLucene = (filters: Filters, tags: Tag[]): string => {\n const queryParts: string[] = [];\n\n // Convert filters to query parts\n for (const field of Object.keys(filters)) {\n const values = filters[field];\n if (values && values.length > 0) {\n if (values.length === 1) {\n queryParts.push(`${field}:${quoteLuceneValue(values[0])}`);\n } else {\n const orValues = values.map(value => `${field}:${quoteLuceneValue(value)}`).join(' OR ');\n queryParts.push(`(${orValues})`);\n }\n }\n }\n\n // Convert tags to query parts\n for (const tag of tags) {\n if (tag.provider && tag.key && tag.value) {\n // Use the new format: tag:provider.key=value\n queryParts.push(`tag:${tag.provider}.${tag.key}=${tag.value}`);\n }\n }\n\n return queryParts.join(' AND ');\n};\n\n/**\n * Parse Lucene query string safely\n */\nconst parseLuceneQuery = (query: string): { filters: Filters; tags: Tag[] } => {\n if (!query.trim()) {\n return { filters: {}, tags: [] };\n }\n\n try {\n const ast = lucene.parse(query);\n return astToFiltersAndTags(ast);\n } catch {\n // Intentionally catch and ignore parse errors - invalid Lucene queries\n // should gracefully fall back to empty state rather than break the UI\n return { filters: {}, tags: [] };\n }\n};\n\n/**\n * Format date to YYYY-MM for URL\n */\nconst formatDateForUrl = (date: Date): string => {\n return format(date, 'yyyy-MM');\n};\n\n/**\n * Parse YYYY-MM from URL to Date\n */\nconst parseDateFromUrl = (dateStr: string): Date | null => {\n try {\n return startOfMonth(parse(dateStr, 'yyyy-MM', new Date()));\n } catch {\n return null;\n }\n};\n\nexport interface InfraWalletLuceneUrlState {\n filters: Filters;\n selectedTags: Tag[];\n monthRange: MonthRange;\n granularity: string;\n aggregatedBy: string;\n}\n\ninterface UseInfraWalletLuceneParamsOptions {\n defaultFilters?: Filters;\n defaultTags?: Tag[];\n defaultMonthRange?: MonthRange;\n defaultGranularity?: string;\n defaultAggregatedBy?: string;\n}\n\n/**\n * Custom hook to manage InfraWallet state in URL search params using Lucene query syntax\n * This enables deep linking and bookmarking of specific filter/view combinations\n */\nexport const useInfraWalletLuceneParams = (options: UseInfraWalletLuceneParamsOptions = {}) => {\n const [searchParams, setSearchParams] = useSearchParams();\n const isInitialMount = useRef(true);\n\n /**\n * Get initial state from URL or use defaults\n */\n const getInitialState = useCallback((): InfraWalletLuceneUrlState => {\n // Parse Lucene query (URL decode first)\n const queryParam = searchParams.get('q') || '';\n const decodedQuery = decodeURIComponent(queryParam);\n const { filters, tags } = parseLuceneQuery(decodedQuery);\n\n // Use parsed values or defaults\n const finalFilters = Object.keys(filters).length > 0 ? filters : options.defaultFilters || {};\n const selectedTags = tags.length > 0 ? tags : options.defaultTags || [];\n\n // Month Range\n const fromParam = searchParams.get('from');\n const toParam = searchParams.get('to');\n let monthRange = options.defaultMonthRange;\n if (fromParam && toParam) {\n const startMonth = parseDateFromUrl(fromParam);\n const endMonth = parseDateFromUrl(toParam);\n if (startMonth && endMonth) {\n monthRange = { startMonth, endMonth };\n }\n }\n\n // Ensure monthRange is never undefined - provide a default\n if (!monthRange) {\n const currentMonth = startOfMonth(new Date());\n monthRange = { startMonth: currentMonth, endMonth: currentMonth };\n }\n\n // Granularity\n const granularityParam = searchParams.get('granularity');\n const granularity = granularityParam || options.defaultGranularity || 'monthly';\n\n const groupByParam = searchParams.get('groupBy');\n const aggregatedBy = groupByParam || options.defaultAggregatedBy || 'none';\n\n return {\n filters: finalFilters,\n selectedTags,\n monthRange,\n granularity,\n aggregatedBy,\n };\n }, [searchParams, options]);\n\n /**\n * Update URL search params with current state\n */\n const updateUrlState = useCallback(\n (state: Partial<InfraWalletLuceneUrlState>) => {\n setSearchParams(\n prev => {\n const newParams = new URLSearchParams(prev);\n\n // Update Lucene query if filters or tags changed\n if (state.filters !== undefined || state.selectedTags !== undefined) {\n // Get current state to merge with new state\n const currentQuery = prev.get('q') || '';\n const decodedCurrentQuery = decodeURIComponent(currentQuery);\n const { filters: currentFilters, tags: currentTags } = parseLuceneQuery(decodedCurrentQuery);\n\n const finalFilters = state.filters ?? currentFilters;\n const finalTags = state.selectedTags ?? currentTags;\n\n const luceneQuery = filtersAndTagsToLucene(finalFilters, finalTags);\n if (luceneQuery) {\n // URL encode the query before setting it\n newParams.set('q', encodeURIComponent(luceneQuery));\n } else {\n newParams.delete('q');\n }\n }\n\n // Update month range\n if (state.monthRange !== undefined) {\n newParams.set('from', formatDateForUrl(state.monthRange.startMonth));\n newParams.set('to', formatDateForUrl(state.monthRange.endMonth));\n }\n\n // Update granularity\n if (state.granularity !== undefined) {\n newParams.set('granularity', state.granularity);\n }\n\n // Update aggregatedBy (groupBy)\n if (state.aggregatedBy !== undefined) {\n newParams.set('groupBy', state.aggregatedBy);\n }\n\n return newParams;\n },\n { replace: true },\n ); // Use replace to avoid creating excessive history entries\n },\n [setSearchParams],\n );\n\n useEffect(() => {\n isInitialMount.current = false;\n }, []);\n\n return {\n getInitialState,\n updateUrlState,\n isInitialMount: isInitialMount.current,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useInfraWalletLuceneParams.esm.js","sources":["../../src/hooks/useInfraWalletLuceneParams.ts"],"sourcesContent":["import { format, parse, startOfMonth } from 'date-fns';\nimport * as lucene from 'lucene';\nimport { useCallback, useEffect, useRef } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Filters, Tag } from '../api/types';\nimport { MonthRange } from '../components/types';\n\n/**\n * Parse tag value into Tag object\n * Supports two formats:\n * 1. provider.key=value (preferred)\n * 2. provider:key:value (fallback)\n */\nconst parseTag = (tagValue: string): Tag | null => {\n // Try provider.key=value format first\n if (tagValue.includes('.') && tagValue.includes('=')) {\n const [providerKey, value] = tagValue.split('=');\n const [provider, key] = providerKey.split('.');\n if (provider && key && value) {\n return { provider, key, value };\n }\n }\n\n // Fallback to provider:key:value format\n if (tagValue.includes(':')) {\n const tagParts = tagValue.split(':');\n if (tagParts.length >= 3) {\n const provider = tagParts[0];\n const key = tagParts[1];\n const value = tagParts.slice(2).join(':'); // In case value contains colons\n return { provider, key, value };\n }\n }\n\n return null;\n};\n\n/**\n * Add a filter value to the filters object, avoiding duplicates\n */\nconst addFilterValue = (filters: Filters, field: string, value: string): void => {\n if (!filters[field]) {\n filters[field] = [];\n }\n if (!filters[field].includes(value)) {\n filters[field].push(value);\n }\n};\n\n/**\n * Convert Lucene AST to Filters and Tags\n */\nconst astToFiltersAndTags = (ast: any): { filters: Filters; tags: Tag[] } => {\n const filters: Filters = {};\n const tags: Tag[] = [];\n\n const traverseAST = (node: any): void => {\n if (!node) return;\n\n // Process field:value pairs\n if (node.field && node.term) {\n if (node.field === 'tag') {\n const tag = parseTag(node.term);\n if (tag) {\n tags.push(tag);\n }\n } else {\n addFilterValue(filters, node.field, node.term);\n }\n }\n\n // Recursively process left and right nodes\n if (node.left) traverseAST(node.left);\n if (node.right) traverseAST(node.right);\n };\n\n traverseAST(ast);\n return { filters, tags };\n};\n\n/**\n * Escape and quote a value for Lucene query if it contains special characters\n */\nconst quoteLuceneValue = (value: string): string => {\n // Check if value contains special Lucene characters that require quoting\n const specialChars = /[/()[\\]{}\\s:]/;\n if (specialChars.test(value)) {\n // Escape any quotes in the value and wrap in quotes\n const escapedQuote = String.raw`\\\"`;\n return `\"${value.replaceAll('\"', escapedQuote)}\"`;\n }\n return value;\n};\n\n/**\n * Quote a tag for Lucene query if a key contains special characters\n */\nconst quoteTag = (provider: string, key: string, value: string): string => {\n const specialChars = /[/()[\\]{}\\s:]/;\n const tag = `${provider}.${key}=${value}`;\n\n // If tag has special character in the key, it needs to be quoted. E.g. tag:\"AWS.key:environment=staging\"\n if (specialChars.test(key)) {\n return `tag:\"${tag}\"`;\n }\n return `tag:${tag}`;\n};\n\n/**\n * Convert Filters and Tags to Lucene query string\n */\nconst filtersAndTagsToLucene = (filters: Filters, tags: Tag[]): string => {\n const queryParts: string[] = [];\n\n // Convert filters to query parts\n for (const field of Object.keys(filters)) {\n const values = filters[field];\n if (values && values.length > 0) {\n if (values.length === 1) {\n queryParts.push(`${field}:${quoteLuceneValue(values[0])}`);\n } else {\n const orValues = values.map(value => `${field}:${quoteLuceneValue(value)}`).join(' OR ');\n queryParts.push(`(${orValues})`);\n }\n }\n }\n\n // Convert tags to query parts\n for (const tag of tags) {\n if (tag.provider && tag.key && tag.value) {\n // Use the new format: tag:provider.key=value\n queryParts.push(quoteTag(tag.provider, tag.key, tag.value));\n }\n }\n\n return queryParts.join(' AND ');\n};\n\n/**\n * Parse Lucene query string safely\n */\nconst parseLuceneQuery = (query: string): { filters: Filters; tags: Tag[] } => {\n if (!query.trim()) {\n return { filters: {}, tags: [] };\n }\n\n try {\n const ast = lucene.parse(query);\n return astToFiltersAndTags(ast);\n } catch {\n // Intentionally catch and ignore parse errors - invalid Lucene queries\n // should gracefully fall back to empty state rather than break the UI\n return { filters: {}, tags: [] };\n }\n};\n\n/**\n * Format date to YYYY-MM for URL\n */\nconst formatDateForUrl = (date: Date): string => {\n return format(date, 'yyyy-MM');\n};\n\n/**\n * Parse YYYY-MM from URL to Date\n */\nconst parseDateFromUrl = (dateStr: string): Date | null => {\n try {\n return startOfMonth(parse(dateStr, 'yyyy-MM', new Date()));\n } catch {\n return null;\n }\n};\n\nexport interface InfraWalletLuceneUrlState {\n filters: Filters;\n selectedTags: Tag[];\n monthRange: MonthRange;\n granularity: string;\n aggregatedBy: string;\n}\n\ninterface UseInfraWalletLuceneParamsOptions {\n defaultFilters?: Filters;\n defaultTags?: Tag[];\n defaultMonthRange?: MonthRange;\n defaultGranularity?: string;\n defaultAggregatedBy?: string;\n}\n\n/**\n * Custom hook to manage InfraWallet state in URL search params using Lucene query syntax\n * This enables deep linking and bookmarking of specific filter/view combinations\n */\nexport const useInfraWalletLuceneParams = (options: UseInfraWalletLuceneParamsOptions = {}) => {\n const [searchParams, setSearchParams] = useSearchParams();\n const isInitialMount = useRef(true);\n\n /**\n * Get initial state from URL or use defaults\n */\n const getInitialState = useCallback((): InfraWalletLuceneUrlState => {\n // Parse Lucene query (URL decode first)\n const queryParam = searchParams.get('q') || '';\n const decodedQuery = decodeURIComponent(queryParam);\n const { filters, tags } = parseLuceneQuery(decodedQuery);\n\n // Use parsed values or defaults\n const finalFilters = Object.keys(filters).length > 0 ? filters : options.defaultFilters || {};\n const selectedTags = tags.length > 0 ? tags : options.defaultTags || [];\n\n // Month Range\n const fromParam = searchParams.get('from');\n const toParam = searchParams.get('to');\n let monthRange = options.defaultMonthRange;\n if (fromParam && toParam) {\n const startMonth = parseDateFromUrl(fromParam);\n const endMonth = parseDateFromUrl(toParam);\n if (startMonth && endMonth) {\n monthRange = { startMonth, endMonth };\n }\n }\n\n // Ensure monthRange is never undefined - provide a default\n if (!monthRange) {\n const currentMonth = startOfMonth(new Date());\n monthRange = { startMonth: currentMonth, endMonth: currentMonth };\n }\n\n // Granularity\n const granularityParam = searchParams.get('granularity');\n const granularity = granularityParam || options.defaultGranularity || 'monthly';\n\n const groupByParam = searchParams.get('groupBy');\n const aggregatedBy = groupByParam || options.defaultAggregatedBy || 'none';\n\n return {\n filters: finalFilters,\n selectedTags,\n monthRange,\n granularity,\n aggregatedBy,\n };\n }, [searchParams, options]);\n\n /**\n * Update URL search params with current state\n */\n const updateUrlState = useCallback(\n (state: Partial<InfraWalletLuceneUrlState>) => {\n setSearchParams(\n prev => {\n const newParams = new URLSearchParams(prev);\n\n // Update Lucene query if filters or tags changed\n if (state.filters !== undefined || state.selectedTags !== undefined) {\n // Get current state to merge with new state\n const currentQuery = prev.get('q') || '';\n const decodedCurrentQuery = decodeURIComponent(currentQuery);\n const { filters: currentFilters, tags: currentTags } = parseLuceneQuery(decodedCurrentQuery);\n\n const finalFilters = state.filters ?? currentFilters;\n const finalTags = state.selectedTags ?? currentTags;\n\n const luceneQuery = filtersAndTagsToLucene(finalFilters, finalTags);\n if (luceneQuery) {\n // URL encode the query before setting it\n newParams.set('q', encodeURIComponent(luceneQuery));\n } else {\n newParams.delete('q');\n }\n }\n\n // Update month range\n if (state.monthRange !== undefined) {\n newParams.set('from', formatDateForUrl(state.monthRange.startMonth));\n newParams.set('to', formatDateForUrl(state.monthRange.endMonth));\n }\n\n // Update granularity\n if (state.granularity !== undefined) {\n newParams.set('granularity', state.granularity);\n }\n\n // Update aggregatedBy (groupBy)\n if (state.aggregatedBy !== undefined) {\n newParams.set('groupBy', state.aggregatedBy);\n }\n\n return newParams;\n },\n { replace: true },\n ); // Use replace to avoid creating excessive history entries\n },\n [setSearchParams],\n );\n\n useEffect(() => {\n isInitialMount.current = false;\n }, []);\n\n return {\n getInitialState,\n updateUrlState,\n isInitialMount: isInitialMount.current,\n };\n};\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electrolux-oss/plugin-infrawallet",
3
- "version": "1.1.0-20251122142002-7ac6f9a",
3
+ "version": "1.1.0-20251202133007-1005ef9",
4
4
  "backstage": {
5
5
  "role": "frontend-plugin",
6
6
  "pluginId": "infrawallet",