meno-core 1.0.53 → 1.1.0
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/.claude/settings.local.json +1 -3
- package/bin/cli.ts +66 -261
- package/build-astro.ts +150 -128
- package/dist/bin/cli.js +42 -185
- package/dist/bin/cli.js.map +2 -2
- package/dist/chunks/chunk-2AR55GYH.js +42 -0
- package/dist/chunks/chunk-2AR55GYH.js.map +7 -0
- package/dist/chunks/{chunk-JGWFTO6P.js → chunk-2IIQK7T3.js} +2624 -1389
- package/dist/chunks/chunk-2IIQK7T3.js.map +7 -0
- package/dist/chunks/chunk-4ZRU52J2.js +169 -0
- package/dist/chunks/chunk-4ZRU52J2.js.map +7 -0
- package/dist/chunks/{chunk-UB44F4Z2.js → chunk-5X4HCN7J.js} +5 -7
- package/dist/chunks/chunk-5X4HCN7J.js.map +7 -0
- package/dist/chunks/{chunk-WQFG7PAH.js → chunk-7CCVOL5M.js} +15 -19
- package/dist/chunks/chunk-7CCVOL5M.js.map +7 -0
- package/dist/chunks/{chunk-YBLHKYFF.js → chunk-AR7LHIFY.js} +8 -2
- package/dist/chunks/chunk-AR7LHIFY.js.map +7 -0
- package/dist/chunks/{chunk-O3NAGJP4.js → chunk-NUP7H7D3.js} +135 -41
- package/dist/chunks/chunk-NUP7H7D3.js.map +7 -0
- package/dist/chunks/{chunk-X754AHS5.js → chunk-QWTQZHG3.js} +194 -90
- package/dist/chunks/chunk-QWTQZHG3.js.map +7 -0
- package/dist/chunks/{chunk-H3GJ4H2U.js → chunk-XTKNX4FW.js} +216 -87
- package/dist/chunks/chunk-XTKNX4FW.js.map +7 -0
- package/dist/chunks/{fs-JGINUXGL.js → fs-G3ANWEFP.js} +2 -2
- package/dist/lib/client/index.js +1003 -475
- package/dist/lib/client/index.js.map +3 -3
- package/dist/lib/server/index.js +14393 -6371
- package/dist/lib/server/index.js.map +4 -4
- package/dist/lib/shared/index.js +342 -101
- package/dist/lib/shared/index.js.map +4 -4
- package/dist/lib/shared/richtext/index.js +1 -1
- package/dist/lib/test-utils/index.js +64 -80
- package/dist/lib/test-utils/index.js.map +2 -2
- package/entries/client-router.tsx +10 -8
- package/lib/client/ClientInitializer.ts +8 -8
- package/lib/client/ErrorBoundary.test.tsx +246 -186
- package/lib/client/ErrorBoundary.tsx +183 -132
- package/lib/client/componentRegistry.test.ts +96 -108
- package/lib/client/componentRegistry.ts +1 -3
- package/lib/client/contexts/ThemeContext.tsx +3 -2
- package/lib/client/core/ComponentBuilder.test.ts +663 -560
- package/lib/client/core/ComponentBuilder.ts +427 -155
- package/lib/client/core/ComponentRenderer.test.tsx +2 -4
- package/lib/client/core/ComponentRenderer.tsx +46 -33
- package/lib/client/core/builders/embedBuilder.ts +242 -54
- package/lib/client/core/builders/linkBuilder.ts +72 -45
- package/lib/client/core/builders/linkNodeBuilder.ts +79 -54
- package/lib/client/core/builders/listBuilder.ts +155 -89
- package/lib/client/core/builders/localeListBuilder.ts +97 -62
- package/lib/client/core/builders/types.ts +5 -5
- package/lib/client/core/cmsTemplateProcessor.ts +8 -9
- package/lib/client/elementRegistry.ts +3 -3
- package/lib/client/fontFamiliesService.test.ts +2 -10
- package/lib/client/fontFamiliesService.ts +3 -3
- package/lib/client/hmr/HMRManager.tsx +47 -30
- package/lib/client/hmrCssReload.ts +49 -14
- package/lib/client/hmrWebSocket.ts +14 -19
- package/lib/client/hooks/useColorVariables.test.ts +21 -21
- package/lib/client/hooks/useColorVariables.ts +23 -18
- package/lib/client/hooks/usePropertyAutocomplete.ts +4 -6
- package/lib/client/hooks/useVariables.ts +6 -4
- package/lib/client/hydration/HydrationUtils.test.ts +24 -25
- package/lib/client/hydration/HydrationUtils.ts +3 -4
- package/lib/client/i18nConfigService.test.ts +2 -7
- package/lib/client/i18nConfigService.ts +2 -2
- package/lib/client/meno-filter/MenoFilter.test.ts +47 -49
- package/lib/client/meno-filter/MenoFilter.ts +14 -15
- package/lib/client/meno-filter/bindings.ts +18 -43
- package/lib/client/meno-filter/init.ts +4 -4
- package/lib/client/meno-filter/renderer.ts +30 -32
- package/lib/client/meno-filter/script.generated.ts +1 -3
- package/lib/client/meno-filter/ui.ts +4 -6
- package/lib/client/meno-filter/updates.ts +18 -23
- package/lib/client/meno-filter/utils.ts +1 -1
- package/lib/client/navigation.test.ts +174 -178
- package/lib/client/navigation.ts +0 -1
- package/lib/client/responsiveStyleResolver.knownTokens.test.ts +71 -0
- package/lib/client/responsiveStyleResolver.test.ts +234 -232
- package/lib/client/responsiveStyleResolver.ts +74 -20
- package/lib/client/routing/RouteLoader.test.ts +24 -25
- package/lib/client/routing/RouteLoader.ts +27 -35
- package/lib/client/routing/Router.tsx +210 -153
- package/lib/client/scripts/ScriptExecutor.test.ts +157 -158
- package/lib/client/scripts/ScriptExecutor.ts +18 -36
- package/lib/client/services/PrefetchService.test.ts +3 -3
- package/lib/client/services/PrefetchService.ts +23 -29
- package/lib/client/styleProcessor.test.ts +9 -9
- package/lib/client/styleProcessor.ts +24 -15
- package/lib/client/styles/StyleInjector.test.ts +122 -115
- package/lib/client/styles/StyleInjector.ts +10 -7
- package/lib/client/styles/UtilityClassCollector.ts +62 -28
- package/lib/client/styles/cspNonce.test.ts +2 -5
- package/lib/client/templateEngine.test.ts +554 -488
- package/lib/client/templateEngine.ts +203 -73
- package/lib/client/theme.test.ts +1 -1
- package/lib/client/theme.ts +0 -1
- package/lib/client/utils/toast.ts +0 -1
- package/lib/server/__integration__/api-routes.test.ts +8 -4
- package/lib/server/__integration__/cms-integration.test.ts +1 -4
- package/lib/server/__integration__/server-lifecycle.test.ts +4 -5
- package/lib/server/__integration__/ssr-rendering.test.ts +47 -37
- package/lib/server/__integration__/static-assets.test.ts +3 -3
- package/lib/server/__integration__/test-helpers.ts +87 -74
- package/lib/server/ab/generateFunctions.ts +12 -10
- package/lib/server/astro/cmsPageEmitter.ts +26 -42
- package/lib/server/astro/componentEmitter.ts +35 -43
- package/lib/server/astro/cssCollector.ts +10 -26
- package/lib/server/astro/nodeToAstro.test.ts +1754 -34
- package/lib/server/astro/nodeToAstro.ts +232 -216
- package/lib/server/astro/normalizeOrphanTemplateProps.test.ts +115 -119
- package/lib/server/astro/normalizeOrphanTemplateProps.ts +11 -18
- package/lib/server/astro/pageEmitter.ts +9 -13
- package/lib/server/astro/tailwindMapper.test.ts +10 -37
- package/lib/server/astro/tailwindMapper.ts +33 -40
- package/lib/server/astro/templateTransformer.ts +17 -20
- package/lib/server/createServer.ts +7 -19
- package/lib/server/cssGenerator.test.ts +35 -44
- package/lib/server/cssGenerator.ts +8 -19
- package/lib/server/fileWatcher.test.ts +164 -13
- package/lib/server/fileWatcher.ts +209 -124
- package/lib/server/index.ts +14 -17
- package/lib/server/jsonLoader.test.ts +39 -2
- package/lib/server/jsonLoader.ts +39 -34
- package/lib/server/middleware/cors.test.ts +21 -21
- package/lib/server/middleware/cors.ts +28 -4
- package/lib/server/middleware/errorHandler.test.ts +7 -5
- package/lib/server/middleware/errorHandler.ts +3 -8
- package/lib/server/middleware/index.ts +0 -1
- package/lib/server/middleware/logger.test.ts +10 -8
- package/lib/server/middleware/logger.ts +17 -29
- package/lib/server/migrateTemplates.ts +3 -3
- package/lib/server/pageCache.test.ts +76 -77
- package/lib/server/pageCache.ts +0 -1
- package/lib/server/projectContext.ts +5 -4
- package/lib/server/providers/fileSystemCMSProvider.test.ts +142 -99
- package/lib/server/providers/fileSystemCMSProvider.ts +62 -38
- package/lib/server/routes/api/cms.test.ts +26 -14
- package/lib/server/routes/api/cms.ts +9 -14
- package/lib/server/routes/api/colors.test.ts +2 -2
- package/lib/server/routes/api/components.ts +31 -35
- package/lib/server/routes/api/config.ts +3 -4
- package/lib/server/routes/api/core-routes.ts +49 -76
- package/lib/server/routes/api/enums.test.ts +2 -2
- package/lib/server/routes/api/functions.ts +9 -17
- package/lib/server/routes/api/index.ts +3 -6
- package/lib/server/routes/api/pages.ts +8 -11
- package/lib/server/routes/api/shared.test.ts +1 -1
- package/lib/server/routes/api/shared.ts +12 -9
- package/lib/server/routes/api/variables.test.ts +3 -5
- package/lib/server/routes/api/variables.ts +1 -1
- package/lib/server/routes/index.ts +25 -28
- package/lib/server/routes/pages.ts +35 -31
- package/lib/server/routes/static.ts +17 -6
- package/lib/server/runtime/bundler.ts +98 -61
- package/lib/server/runtime/fs.ts +16 -26
- package/lib/server/runtime/httpServer.ts +8 -12
- package/lib/server/services/ColorService.test.ts +3 -3
- package/lib/server/services/ColorService.ts +37 -29
- package/lib/server/services/EnumService.test.ts +4 -8
- package/lib/server/services/EnumService.ts +11 -3
- package/lib/server/services/VariableService.test.ts +8 -12
- package/lib/server/services/VariableService.ts +11 -3
- package/lib/server/services/cmsService.test.ts +158 -120
- package/lib/server/services/cmsService.ts +36 -146
- package/lib/server/services/componentService.test.ts +125 -45
- package/lib/server/services/componentService.ts +70 -46
- package/lib/server/services/configService.test.ts +22 -45
- package/lib/server/services/configService.ts +50 -27
- package/lib/server/services/fileWatcherService.ts +42 -8
- package/lib/server/services/index.ts +0 -1
- package/lib/server/services/pageService.test.ts +8 -10
- package/lib/server/services/pageService.ts +32 -18
- package/lib/server/ssr/attributeBuilder.ts +18 -8
- package/lib/server/ssr/buildErrorOverlay.ts +11 -12
- package/lib/server/ssr/clientDataInjector.ts +7 -21
- package/lib/server/ssr/cmsSSRProcessor.ts +4 -8
- package/lib/server/ssr/cssCollector.ts +1 -1
- package/lib/server/ssr/errorOverlay.test.ts +1 -1
- package/lib/server/ssr/errorOverlay.ts +3 -9
- package/lib/server/ssr/htmlGenerator.nonce.test.ts +9 -14
- package/lib/server/ssr/htmlGenerator.test.ts +120 -44
- package/lib/server/ssr/htmlGenerator.ts +126 -91
- package/lib/server/ssr/imageMetadata.test.ts +3 -1
- package/lib/server/ssr/imageMetadata.ts +27 -21
- package/lib/server/ssr/jsCollector.test.ts +8 -18
- package/lib/server/ssr/jsCollector.ts +3 -8
- package/lib/server/ssr/liveReloadIntegration.test.ts +76 -36
- package/lib/server/ssr/metaTagGenerator.ts +2 -2
- package/lib/server/ssr/ssrRenderer.branches.test.ts +1103 -0
- package/lib/server/ssr/ssrRenderer.test.ts +316 -256
- package/lib/server/ssr/ssrRenderer.ts +795 -243
- package/lib/server/ssrRenderer.test.ts +1048 -954
- package/lib/server/utils/jsonLineMapper.test.ts +28 -28
- package/lib/server/utils/jsonLineMapper.ts +7 -7
- package/lib/server/validateStyleCoverage.ts +18 -21
- package/lib/server/websocketManager.ts +28 -19
- package/lib/shared/attributeNodeUtils.test.ts +15 -15
- package/lib/shared/attributeNodeUtils.ts +5 -12
- package/lib/shared/breakpoints.test.ts +5 -5
- package/lib/shared/breakpoints.ts +4 -11
- package/lib/shared/cmsQuery.test.ts +81 -0
- package/lib/shared/cmsQuery.ts +92 -0
- package/lib/shared/cmsQueryParser.test.ts +50 -42
- package/lib/shared/cmsQueryParser.ts +60 -38
- package/lib/shared/colorConversions.ts +9 -9
- package/lib/shared/colorVariableUtils.test.ts +27 -5
- package/lib/shared/colorVariableUtils.ts +21 -12
- package/lib/shared/componentRefs.ts +1 -5
- package/lib/shared/constants.test.ts +3 -3
- package/lib/shared/constants.ts +8 -8
- package/lib/shared/cssGeneration.test.ts +285 -144
- package/lib/shared/cssGeneration.ts +217 -531
- package/lib/shared/cssNamedColors.ts +152 -30
- package/lib/shared/cssProperties.test.ts +69 -70
- package/lib/shared/cssProperties.ts +298 -114
- package/lib/shared/elementClassName.test.ts +109 -109
- package/lib/shared/elementClassName.ts +3 -3
- package/lib/shared/elementUtils.ts +12 -16
- package/lib/shared/errorLogger.test.ts +12 -12
- package/lib/shared/errorLogger.ts +2 -10
- package/lib/shared/errors.test.ts +2 -13
- package/lib/shared/errors.ts +2 -8
- package/lib/shared/expressionEvaluator.test.ts +145 -0
- package/lib/shared/expressionEvaluator.ts +52 -24
- package/lib/shared/fontLoader.test.ts +32 -18
- package/lib/shared/fontLoader.ts +2 -2
- package/lib/shared/friendlyError.ts +2 -3
- package/lib/shared/gradientUtils.test.ts +3 -7
- package/lib/shared/gradientUtils.ts +17 -14
- package/lib/shared/hrefRefs.test.ts +2 -2
- package/lib/shared/hrefRefs.ts +2 -10
- package/lib/shared/i18n.test.ts +4 -4
- package/lib/shared/i18n.ts +18 -38
- package/lib/shared/index.ts +27 -0
- package/lib/shared/inlineSvgStyleRules.ts +14 -13
- package/lib/shared/interactiveStyleMappings.test.ts +32 -54
- package/lib/shared/interactiveStyleMappings.ts +11 -24
- package/lib/shared/interactiveStyles.test.ts +165 -188
- package/lib/shared/interfaces/contentProvider.ts +1 -1
- package/lib/shared/itemTemplateUtils.test.ts +11 -17
- package/lib/shared/itemTemplateUtils.ts +27 -39
- package/lib/shared/jsonRepair.ts +16 -10
- package/lib/shared/libraryLoader.test.ts +21 -55
- package/lib/shared/libraryLoader.ts +7 -22
- package/lib/shared/linkUtils.ts +1 -1
- package/lib/shared/logger.test.ts +66 -0
- package/lib/shared/logger.ts +94 -0
- package/lib/shared/markdown.ts +25 -0
- package/lib/shared/netlifyLocale404.test.ts +179 -0
- package/lib/shared/netlifyLocale404.ts +110 -0
- package/lib/shared/nodeUtils.test.ts +28 -16
- package/lib/shared/nodeUtils.ts +76 -23
- package/lib/shared/pathArrayUtils.test.ts +1 -2
- package/lib/shared/pathArrayUtils.ts +1 -1
- package/lib/shared/pathSecurity.ts +2 -2
- package/lib/shared/pathUtils.test.ts +4 -6
- package/lib/shared/pathUtils.ts +42 -49
- package/lib/shared/paths/Path.test.ts +2 -2
- package/lib/shared/paths/Path.ts +0 -1
- package/lib/shared/paths/PathConverter.test.ts +1 -1
- package/lib/shared/paths/PathConverter.ts +17 -20
- package/lib/shared/paths/PathUtils.ts +13 -13
- package/lib/shared/paths/PathValidator.test.ts +2 -15
- package/lib/shared/paths/PathValidator.ts +12 -10
- package/lib/shared/paths/index.ts +1 -2
- package/lib/shared/permissions.test.ts +168 -0
- package/lib/shared/permissions.ts +162 -0
- package/lib/shared/propResolver.test.ts +240 -244
- package/lib/shared/propResolver.ts +15 -26
- package/lib/shared/pxToRem.test.ts +7 -6
- package/lib/shared/pxToRem.ts +2 -5
- package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +12 -6
- package/lib/shared/registry/ClientRegistry.ts +0 -2
- package/lib/shared/registry/ComponentRegistry.test.ts +46 -32
- package/lib/shared/registry/ComponentRegistry.ts +12 -9
- package/lib/shared/registry/NodeTypeDefinition.ts +16 -9
- package/lib/shared/registry/RegistryManager.ts +1 -2
- package/lib/shared/registry/SSRRegistry.ts +0 -2
- package/lib/shared/registry/createNodeType.ts +7 -9
- package/lib/shared/registry/defineNodeType.ts +2 -6
- package/lib/shared/registry/fieldPresets.ts +3 -1
- package/lib/shared/registry/index.ts +0 -1
- package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +14 -15
- package/lib/shared/registry/nodeTypes/CustomNodeType.ts +103 -0
- package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +18 -11
- package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +48 -19
- package/lib/shared/registry/nodeTypes/IslandNodeType.ts +129 -0
- package/lib/shared/registry/nodeTypes/LinkNodeType.ts +21 -19
- package/lib/shared/registry/nodeTypes/ListNodeType.ts +117 -77
- package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +27 -21
- package/lib/shared/registry/nodeTypes/MarkdownNodeType.ts +78 -0
- package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +12 -8
- package/lib/shared/registry/nodeTypes/index.ts +26 -3
- package/lib/shared/responsiveScaling.test.ts +16 -34
- package/lib/shared/responsiveScaling.ts +61 -42
- package/lib/shared/responsiveStyleUtils.test.ts +0 -1
- package/lib/shared/responsiveStyleUtils.ts +11 -13
- package/lib/shared/richtext/htmlToTiptap.test.ts +139 -130
- package/lib/shared/richtext/htmlToTiptap.ts +2 -4
- package/lib/shared/richtext/tiptapToHtml.test.ts +5 -6
- package/lib/shared/richtext/types.ts +1 -8
- package/lib/shared/slugTranslator.test.ts +13 -13
- package/lib/shared/slugTranslator.ts +12 -16
- package/lib/shared/slugify.ts +9 -15
- package/lib/shared/styleNodeUtils.test.ts +8 -8
- package/lib/shared/styleNodeUtils.ts +18 -20
- package/lib/shared/styleUtils.test.ts +87 -61
- package/lib/shared/styleUtils.ts +5 -6
- package/lib/shared/themeDefaults.test.ts +11 -14
- package/lib/shared/themeDefaults.ts +3 -4
- package/lib/shared/tree/PathBuilder.test.ts +63 -145
- package/lib/shared/tree/PathBuilder.ts +59 -47
- package/lib/shared/treePathUtils.test.ts +51 -12
- package/lib/shared/treePathUtils.ts +91 -60
- package/lib/shared/types/api.ts +105 -8
- package/lib/shared/types/cms.test.ts +34 -0
- package/lib/shared/types/cms.ts +90 -34
- package/lib/shared/types/comment.ts +49 -16
- package/lib/shared/types/components.ts +51 -25
- package/lib/shared/types/errors.test.ts +1 -6
- package/lib/shared/types/errors.ts +3 -7
- package/lib/shared/types/experiments.ts +28 -28
- package/lib/shared/types/index.ts +25 -2
- package/lib/shared/types/permissions.ts +139 -0
- package/lib/shared/types/styles.ts +0 -1
- package/lib/shared/types/variables.test.ts +4 -13
- package/lib/shared/types/variables.ts +51 -30
- package/lib/shared/types.ts +1 -2
- package/lib/shared/utilityClassConfig.ts +751 -321
- package/lib/shared/utilityClassMapper.durability.test.ts +117 -0
- package/lib/shared/utilityClassMapper.test.ts +433 -95
- package/lib/shared/utilityClassMapper.ts +322 -249
- package/lib/shared/utilityClassNames.test.ts +38 -0
- package/lib/shared/utilityClassNames.ts +458 -0
- package/lib/shared/utils.test.ts +2 -10
- package/lib/shared/utils.ts +19 -10
- package/lib/shared/validation/cmsValidators.ts +2 -1
- package/lib/shared/validation/commentValidators.test.ts +53 -0
- package/lib/shared/validation/commentValidators.ts +12 -1
- package/lib/shared/validation/index.ts +1 -0
- package/lib/shared/validation/permissionsValidators.test.ts +49 -0
- package/lib/shared/validation/permissionsValidators.ts +49 -0
- package/lib/shared/validation/propValidator.test.ts +19 -21
- package/lib/shared/validation/propValidator.ts +13 -18
- package/lib/shared/validation/schemas.test.ts +64 -32
- package/lib/shared/validation/schemas.ts +616 -345
- package/lib/shared/validation/validators.test.ts +3 -8
- package/lib/shared/validation/validators.ts +89 -68
- package/lib/shared/viewportUnits.integration.test.ts +14 -10
- package/lib/shared/viewportUnits.test.ts +24 -23
- package/lib/shared/viewportUnits.ts +12 -5
- package/lib/test-utils/dom-setup.ts +1 -1
- package/lib/test-utils/factories/ConsoleMockFactory.ts +10 -14
- package/lib/test-utils/factories/DomMockFactory.ts +17 -23
- package/lib/test-utils/factories/EventMockFactory.ts +7 -13
- package/lib/test-utils/factories/FetchMockFactory.ts +39 -57
- package/lib/test-utils/factories/ServerMockFactory.ts +6 -10
- package/lib/test-utils/factories/StoreMockFactory.ts +18 -29
- package/lib/test-utils/fixtures.ts +45 -45
- package/lib/test-utils/helpers/asyncHelpers.test.ts +15 -18
- package/lib/test-utils/helpers/asyncHelpers.ts +11 -20
- package/lib/test-utils/helpers.ts +1 -5
- package/lib/test-utils/index.ts +0 -4
- package/lib/test-utils/mockFactories.ts +13 -19
- package/lib/test-utils/mocks.ts +6 -4
- package/package.json +3 -5
- package/scripts/build-for-publish.mjs +2 -4
- package/scripts/build-meno-filter.ts +4 -7
- package/tsconfig.json +1 -0
- package/vite.config.ts +4 -4
- package/build-next.ts +0 -1361
- package/build-static.test.ts +0 -424
- package/build-static.ts +0 -1074
- package/dist/build-static.js +0 -36
- package/dist/chunks/chunk-2MHDV5BF.js +0 -251
- package/dist/chunks/chunk-2MHDV5BF.js.map +0 -7
- package/dist/chunks/chunk-AZQYF6KE.js +0 -559
- package/dist/chunks/chunk-AZQYF6KE.js.map +0 -7
- package/dist/chunks/chunk-GZHGVVW3.js +0 -322
- package/dist/chunks/chunk-GZHGVVW3.js.map +0 -7
- package/dist/chunks/chunk-H3GJ4H2U.js.map +0 -7
- package/dist/chunks/chunk-I7YIGZXT.js +0 -467
- package/dist/chunks/chunk-I7YIGZXT.js.map +0 -7
- package/dist/chunks/chunk-IGYR22T6.js +0 -6192
- package/dist/chunks/chunk-IGYR22T6.js.map +0 -7
- package/dist/chunks/chunk-JGP5A3Y5.js +0 -1136
- package/dist/chunks/chunk-JGP5A3Y5.js.map +0 -7
- package/dist/chunks/chunk-JGWFTO6P.js.map +0 -7
- package/dist/chunks/chunk-O3NAGJP4.js.map +0 -7
- package/dist/chunks/chunk-QB2LNO4W.js +0 -77
- package/dist/chunks/chunk-QB2LNO4W.js.map +0 -7
- package/dist/chunks/chunk-R6XHAFBF.js +0 -3821
- package/dist/chunks/chunk-R6XHAFBF.js.map +0 -7
- package/dist/chunks/chunk-UB44F4Z2.js.map +0 -7
- package/dist/chunks/chunk-WQFG7PAH.js.map +0 -7
- package/dist/chunks/chunk-X754AHS5.js.map +0 -7
- package/dist/chunks/chunk-YBLHKYFF.js.map +0 -7
- package/dist/chunks/configService-R3OGU2UD.js +0 -13
- package/dist/chunks/configService-R3OGU2UD.js.map +0 -7
- package/dist/chunks/constants-STK2YBIW.js +0 -46
- package/dist/chunks/constants-STK2YBIW.js.map +0 -7
- package/dist/chunks/fs-JGINUXGL.js.map +0 -7
- package/dist/entries/server-router.js +0 -67
- package/dist/entries/server-router.js.map +0 -7
- package/entries/server-router.tsx +0 -81
- package/lib/server/providers/fileSystemPageProvider.ts +0 -160
- package/lib/server/webflow/buildWebflow.ts +0 -635
- package/lib/server/webflow/index.ts +0 -23
- package/lib/server/webflow/nodeToWebflow.test.ts +0 -3170
- package/lib/server/webflow/nodeToWebflow.ts +0 -2435
- package/lib/server/webflow/styleMapper.test.ts +0 -389
- package/lib/server/webflow/styleMapper.ts +0 -695
- package/lib/server/webflow/templateWrapper.ts +0 -49
- package/lib/server/webflow/types.ts +0 -396
- /package/dist/{build-static.js.map → chunks/fs-G3ANWEFP.js.map} +0 -0
|
@@ -50,7 +50,7 @@ describe('MenoFilter', () => {
|
|
|
50
50
|
await filter.init();
|
|
51
51
|
|
|
52
52
|
expect(filter.getAll()).toHaveLength(4);
|
|
53
|
-
expect(filter.getAll()[0]
|
|
53
|
+
expect(filter.getAll()[0]!._id).toBe('1');
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
test('should handle missing data gracefully', async () => {
|
|
@@ -83,7 +83,7 @@ describe('MenoFilter', () => {
|
|
|
83
83
|
Promise.resolve({
|
|
84
84
|
ok: true,
|
|
85
85
|
json: () => Promise.resolve(sampleItems),
|
|
86
|
-
})
|
|
86
|
+
}),
|
|
87
87
|
);
|
|
88
88
|
const originalFetch = (globalThis as any).fetch;
|
|
89
89
|
(globalThis as any).fetch = mockFetch;
|
|
@@ -127,7 +127,7 @@ describe('MenoFilter', () => {
|
|
|
127
127
|
Promise.resolve({
|
|
128
128
|
ok: false,
|
|
129
129
|
status: 404,
|
|
130
|
-
})
|
|
130
|
+
}),
|
|
131
131
|
);
|
|
132
132
|
const originalFetch = (globalThis as any).fetch;
|
|
133
133
|
(globalThis as any).fetch = mockFetch;
|
|
@@ -157,7 +157,7 @@ describe('MenoFilter', () => {
|
|
|
157
157
|
Promise.resolve({
|
|
158
158
|
ok: true,
|
|
159
159
|
json: () => Promise.resolve([{ _id: 'fetch', title: 'Fetch Data' }]),
|
|
160
|
-
})
|
|
160
|
+
}),
|
|
161
161
|
);
|
|
162
162
|
const originalFetch = (globalThis as any).fetch;
|
|
163
163
|
(globalThis as any).fetch = mockFetch;
|
|
@@ -168,7 +168,7 @@ describe('MenoFilter', () => {
|
|
|
168
168
|
|
|
169
169
|
// Should have inline data, not fetch data
|
|
170
170
|
expect(filter.getAll()).toHaveLength(1);
|
|
171
|
-
expect(filter.getAll()[0]
|
|
171
|
+
expect(filter.getAll()[0]!._id).toBe('inline');
|
|
172
172
|
expect(mockFetch).not.toHaveBeenCalled();
|
|
173
173
|
} finally {
|
|
174
174
|
(globalThis as any).fetch = originalFetch;
|
|
@@ -193,14 +193,14 @@ describe('MenoFilter', () => {
|
|
|
193
193
|
const result = filter.filter({ category: 'tech' });
|
|
194
194
|
|
|
195
195
|
expect(result).toHaveLength(3);
|
|
196
|
-
expect(result.every(item => item.category === 'tech')).toBe(true);
|
|
196
|
+
expect(result.every((item) => item.category === 'tech')).toBe(true);
|
|
197
197
|
});
|
|
198
198
|
|
|
199
199
|
test('should filter by multiple criteria (AND logic)', () => {
|
|
200
200
|
const result = filter.filter({ category: 'tech', featured: true });
|
|
201
201
|
|
|
202
202
|
expect(result).toHaveLength(1);
|
|
203
|
-
expect(result[0]
|
|
203
|
+
expect(result[0]!.title).toBe('Hello World');
|
|
204
204
|
});
|
|
205
205
|
|
|
206
206
|
test('should skip empty/undefined criteria values', () => {
|
|
@@ -217,14 +217,14 @@ describe('MenoFilter', () => {
|
|
|
217
217
|
|
|
218
218
|
test('should emit to subscribers on filter', () => {
|
|
219
219
|
let emittedItems: CMSItemClient[] = [];
|
|
220
|
-
filter.subscribe(items => {
|
|
220
|
+
filter.subscribe((items) => {
|
|
221
221
|
emittedItems = items;
|
|
222
222
|
});
|
|
223
223
|
|
|
224
224
|
filter.filter({ category: 'design' });
|
|
225
225
|
|
|
226
226
|
expect(emittedItems).toHaveLength(1);
|
|
227
|
-
expect(emittedItems[0]
|
|
227
|
+
expect(emittedItems[0]!.category).toBe('design');
|
|
228
228
|
});
|
|
229
229
|
});
|
|
230
230
|
|
|
@@ -245,8 +245,8 @@ describe('MenoFilter', () => {
|
|
|
245
245
|
const result = filter.search('world');
|
|
246
246
|
|
|
247
247
|
expect(result).toHaveLength(2);
|
|
248
|
-
expect(result.map(i => i.title)).toContain('Hello World');
|
|
249
|
-
expect(result.map(i => i.title)).toContain('Goodbye World');
|
|
248
|
+
expect(result.map((i) => i.title)).toContain('Hello World');
|
|
249
|
+
expect(result.map((i) => i.title)).toContain('Goodbye World');
|
|
250
250
|
});
|
|
251
251
|
|
|
252
252
|
test('should search specified fields only', () => {
|
|
@@ -278,22 +278,22 @@ describe('MenoFilter', () => {
|
|
|
278
278
|
test('should sort ascending by default', () => {
|
|
279
279
|
const result = filter.sort('title');
|
|
280
280
|
|
|
281
|
-
expect(result[0]
|
|
282
|
-
expect(result[3]
|
|
281
|
+
expect(result[0]!.title).toBe('Coding Best Practices');
|
|
282
|
+
expect(result[3]!.title).toBe('Hello World');
|
|
283
283
|
});
|
|
284
284
|
|
|
285
285
|
test('should sort descending', () => {
|
|
286
286
|
const result = filter.sort('title', 'desc');
|
|
287
287
|
|
|
288
|
-
expect(result[0]
|
|
289
|
-
expect(result[3]
|
|
288
|
+
expect(result[0]!.title).toBe('Hello World');
|
|
289
|
+
expect(result[3]!.title).toBe('Coding Best Practices');
|
|
290
290
|
});
|
|
291
291
|
|
|
292
292
|
test('should sort numbers correctly', () => {
|
|
293
293
|
const result = filter.sort('views', 'desc');
|
|
294
294
|
|
|
295
|
-
expect(result[0]
|
|
296
|
-
expect(result[3]
|
|
295
|
+
expect(result[0]!.views).toBe(200);
|
|
296
|
+
expect(result[3]!.views).toBe(50);
|
|
297
297
|
});
|
|
298
298
|
|
|
299
299
|
test('should handle undefined values in sort', () => {
|
|
@@ -312,7 +312,7 @@ describe('MenoFilter', () => {
|
|
|
312
312
|
const result = filter2.sort('views', 'asc');
|
|
313
313
|
|
|
314
314
|
// Undefined values should be sorted last in ascending order
|
|
315
|
-
expect(result[result.length - 1]
|
|
315
|
+
expect(result[result.length - 1]!.title).toBe('No Views');
|
|
316
316
|
});
|
|
317
317
|
});
|
|
318
318
|
|
|
@@ -337,9 +337,7 @@ describe('MenoFilter', () => {
|
|
|
337
337
|
});
|
|
338
338
|
|
|
339
339
|
test('should find item by _filename', () => {
|
|
340
|
-
const itemsWithFilename = [
|
|
341
|
-
{ _id: '1', _filename: 'hello-world', title: 'Hello' },
|
|
342
|
-
];
|
|
340
|
+
const itemsWithFilename = [{ _id: '1', _filename: 'hello-world', title: 'Hello' }];
|
|
343
341
|
const mockElement = {
|
|
344
342
|
textContent: JSON.stringify(itemsWithFilename),
|
|
345
343
|
};
|
|
@@ -424,7 +422,7 @@ describe('MenoFilter', () => {
|
|
|
424
422
|
await filter.init();
|
|
425
423
|
|
|
426
424
|
let receivedItems: CMSItemClient[] = [];
|
|
427
|
-
filter.subscribe(items => {
|
|
425
|
+
filter.subscribe((items) => {
|
|
428
426
|
receivedItems = items;
|
|
429
427
|
});
|
|
430
428
|
|
|
@@ -484,8 +482,8 @@ describe('MenoFilter', () => {
|
|
|
484
482
|
const result = filter.getFiltered();
|
|
485
483
|
|
|
486
484
|
expect(result).toHaveLength(2);
|
|
487
|
-
expect(result[0]
|
|
488
|
-
expect(result[1]
|
|
485
|
+
expect(result[0]!.title).toBe('Goodbye World');
|
|
486
|
+
expect(result[1]!.title).toBe('Hello World');
|
|
489
487
|
});
|
|
490
488
|
});
|
|
491
489
|
|
|
@@ -517,8 +515,8 @@ describe('MenoFilter', () => {
|
|
|
517
515
|
|
|
518
516
|
const pageItems = filter.getItems();
|
|
519
517
|
expect(pageItems).toHaveLength(3);
|
|
520
|
-
expect(pageItems[0]
|
|
521
|
-
expect(pageItems[2]
|
|
518
|
+
expect(pageItems[0]!._id).toBe('1');
|
|
519
|
+
expect(pageItems[2]!._id).toBe('3');
|
|
522
520
|
});
|
|
523
521
|
|
|
524
522
|
test('should return correct page info', async () => {
|
|
@@ -546,7 +544,7 @@ describe('MenoFilter', () => {
|
|
|
546
544
|
|
|
547
545
|
const pageItems = filter.setPage(2);
|
|
548
546
|
expect(pageItems).toHaveLength(3);
|
|
549
|
-
expect(pageItems[0]
|
|
547
|
+
expect(pageItems[0]!._id).toBe('4');
|
|
550
548
|
expect(filter.getPageInfo().current).toBe(2);
|
|
551
549
|
});
|
|
552
550
|
|
|
@@ -607,7 +605,7 @@ describe('MenoFilter', () => {
|
|
|
607
605
|
|
|
608
606
|
const lastPageItems = filter.setPage(4);
|
|
609
607
|
expect(lastPageItems).toHaveLength(1); // 10 items, pages 1-3 have 3 each, page 4 has 1
|
|
610
|
-
expect(lastPageItems[0]
|
|
608
|
+
expect(lastPageItems[0]!._id).toBe('10');
|
|
611
609
|
});
|
|
612
610
|
|
|
613
611
|
test('filter() should reset to page 1', async () => {
|
|
@@ -648,18 +646,18 @@ describe('MenoFilter', () => {
|
|
|
648
646
|
await filter.init();
|
|
649
647
|
|
|
650
648
|
let receivedItems: CMSItemClient[] = [];
|
|
651
|
-
filter.subscribe(items => {
|
|
649
|
+
filter.subscribe((items) => {
|
|
652
650
|
receivedItems = items;
|
|
653
651
|
});
|
|
654
652
|
|
|
655
653
|
// Initial subscription gets first page
|
|
656
654
|
expect(receivedItems).toHaveLength(3);
|
|
657
|
-
expect(receivedItems[0]
|
|
655
|
+
expect(receivedItems[0]!._id).toBe('1');
|
|
658
656
|
|
|
659
657
|
// Change page
|
|
660
658
|
filter.setPage(2);
|
|
661
659
|
expect(receivedItems).toHaveLength(3);
|
|
662
|
-
expect(receivedItems[0]
|
|
660
|
+
expect(receivedItems[0]!._id).toBe('4');
|
|
663
661
|
});
|
|
664
662
|
|
|
665
663
|
test('getFiltered() should return all filtered items ignoring pagination', async () => {
|
|
@@ -701,7 +699,7 @@ describe('MenoFilter', () => {
|
|
|
701
699
|
const result = filter.filter({ price: { $gt: 100 } });
|
|
702
700
|
|
|
703
701
|
expect(result).toHaveLength(2);
|
|
704
|
-
expect(result.map(i => i.price)).toEqual([200, 150]);
|
|
702
|
+
expect(result.map((i) => i.price)).toEqual([200, 150]);
|
|
705
703
|
});
|
|
706
704
|
|
|
707
705
|
test('should filter numbers from string criteria', async () => {
|
|
@@ -718,7 +716,7 @@ describe('MenoFilter', () => {
|
|
|
718
716
|
const result = filter.filter({ price: { $gte: '100', $lte: '150' } });
|
|
719
717
|
|
|
720
718
|
expect(result).toHaveLength(2);
|
|
721
|
-
expect(result.map(i => i.price)).toEqual([100, 150]);
|
|
719
|
+
expect(result.map((i) => i.price)).toEqual([100, 150]);
|
|
722
720
|
});
|
|
723
721
|
|
|
724
722
|
test('should filter dates with type coercion', async () => {
|
|
@@ -735,7 +733,7 @@ describe('MenoFilter', () => {
|
|
|
735
733
|
const result = filter.filter({ date: { $gt: '2024-01-31' } });
|
|
736
734
|
|
|
737
735
|
expect(result).toHaveLength(2);
|
|
738
|
-
expect(result.map(i => i.date)).toEqual(['2024-02-15', '2024-03-15']);
|
|
736
|
+
expect(result.map((i) => i.date)).toEqual(['2024-02-15', '2024-03-15']);
|
|
739
737
|
});
|
|
740
738
|
|
|
741
739
|
test('should filter booleans with type coercion', async () => {
|
|
@@ -752,7 +750,7 @@ describe('MenoFilter', () => {
|
|
|
752
750
|
const result = filter.filter({ featured: 'true' });
|
|
753
751
|
|
|
754
752
|
expect(result).toHaveLength(2);
|
|
755
|
-
expect(result.every(i => i.featured === true)).toBe(true);
|
|
753
|
+
expect(result.every((i) => i.featured === true)).toBe(true);
|
|
756
754
|
});
|
|
757
755
|
|
|
758
756
|
test('setFieldType() should update field types', async () => {
|
|
@@ -773,7 +771,7 @@ describe('MenoFilter', () => {
|
|
|
773
771
|
result = filter.filter({ price: { $gt: 100 } });
|
|
774
772
|
|
|
775
773
|
expect(result).toHaveLength(2);
|
|
776
|
-
expect(result.map(i => i.price)).toEqual([200, 150]);
|
|
774
|
+
expect(result.map((i) => i.price)).toEqual([200, 150]);
|
|
777
775
|
});
|
|
778
776
|
|
|
779
777
|
test('setFieldTypes() should set multiple types', async () => {
|
|
@@ -820,7 +818,7 @@ describe('MenoFilter', () => {
|
|
|
820
818
|
const result = filter.filterRange('price', { min: 100, max: 200 });
|
|
821
819
|
|
|
822
820
|
expect(result).toHaveLength(3);
|
|
823
|
-
expect(result.map(i => i.price).sort((a, b) => (a as number) - (b as number))).toEqual([100, 150, 200]);
|
|
821
|
+
expect(result.map((i) => i.price).sort((a, b) => (a as number) - (b as number))).toEqual([100, 150, 200]);
|
|
824
822
|
});
|
|
825
823
|
|
|
826
824
|
test('should filter with only min', async () => {
|
|
@@ -836,7 +834,7 @@ describe('MenoFilter', () => {
|
|
|
836
834
|
const result = filter.filterRange('price', { min: 150 });
|
|
837
835
|
|
|
838
836
|
expect(result).toHaveLength(3);
|
|
839
|
-
expect(result.every(i => (i.price as number) >= 150)).toBe(true);
|
|
837
|
+
expect(result.every((i) => (i.price as number) >= 150)).toBe(true);
|
|
840
838
|
});
|
|
841
839
|
|
|
842
840
|
test('should filter with only max', async () => {
|
|
@@ -852,7 +850,7 @@ describe('MenoFilter', () => {
|
|
|
852
850
|
const result = filter.filterRange('price', { max: 100 });
|
|
853
851
|
|
|
854
852
|
expect(result).toHaveLength(2);
|
|
855
|
-
expect(result.every(i => (i.price as number) <= 100)).toBe(true);
|
|
853
|
+
expect(result.every((i) => (i.price as number) <= 100)).toBe(true);
|
|
856
854
|
});
|
|
857
855
|
|
|
858
856
|
test('should clear filter when both min and max are empty', async () => {
|
|
@@ -932,7 +930,7 @@ describe('MenoFilter', () => {
|
|
|
932
930
|
const result = filter.search('react', ['title']);
|
|
933
931
|
|
|
934
932
|
expect(result).toHaveLength(1);
|
|
935
|
-
expect(result[0]
|
|
933
|
+
expect(result[0]!.title).toBe('React Hooks Tutorial');
|
|
936
934
|
});
|
|
937
935
|
|
|
938
936
|
test('should match with typos when fuzzy enabled', async () => {
|
|
@@ -956,7 +954,7 @@ describe('MenoFilter', () => {
|
|
|
956
954
|
const result = filter.search('recat', ['title']);
|
|
957
955
|
|
|
958
956
|
expect(result.length).toBeGreaterThanOrEqual(1);
|
|
959
|
-
expect(result.some(i => i.title === 'React')).toBe(true);
|
|
957
|
+
expect(result.some((i) => i.title === 'React')).toBe(true);
|
|
960
958
|
});
|
|
961
959
|
|
|
962
960
|
test('should use exact match for short queries (< 3 chars)', async () => {
|
|
@@ -973,7 +971,7 @@ describe('MenoFilter', () => {
|
|
|
973
971
|
const result = filter.search('js', ['title']);
|
|
974
972
|
|
|
975
973
|
expect(result).toHaveLength(1);
|
|
976
|
-
expect(result[0]
|
|
974
|
+
expect(result[0]!.title).toBe('Vue.js Components Guide');
|
|
977
975
|
});
|
|
978
976
|
|
|
979
977
|
test('setFuzzySearch() should enable/disable fuzzy search', async () => {
|
|
@@ -1022,7 +1020,7 @@ describe('MenoFilter', () => {
|
|
|
1022
1020
|
const result = filter.search('javascript', ['title']);
|
|
1023
1021
|
|
|
1024
1022
|
expect(result).toHaveLength(1);
|
|
1025
|
-
expect(result[0]
|
|
1023
|
+
expect(result[0]!.title).toBe('JavaScript Best Practices');
|
|
1026
1024
|
});
|
|
1027
1025
|
});
|
|
1028
1026
|
|
|
@@ -1065,7 +1063,7 @@ describe('MenoFilter', () => {
|
|
|
1065
1063
|
|
|
1066
1064
|
// Should have called replaceState (default mode)
|
|
1067
1065
|
expect(mockHistory.replaceState).toHaveBeenCalled();
|
|
1068
|
-
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]
|
|
1066
|
+
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]!;
|
|
1069
1067
|
expect(lastCall[2]).toContain('filter.category=tech');
|
|
1070
1068
|
});
|
|
1071
1069
|
|
|
@@ -1080,7 +1078,7 @@ describe('MenoFilter', () => {
|
|
|
1080
1078
|
filter.filter({ category: 'design' });
|
|
1081
1079
|
|
|
1082
1080
|
expect(mockHistory.pushState).toHaveBeenCalled();
|
|
1083
|
-
const lastCall = mockHistory.pushState.mock.calls[mockHistory.pushState.mock.calls.length - 1]
|
|
1081
|
+
const lastCall = mockHistory.pushState.mock.calls[mockHistory.pushState.mock.calls.length - 1]!;
|
|
1084
1082
|
expect(lastCall[2]).toContain('filter.category=design');
|
|
1085
1083
|
});
|
|
1086
1084
|
|
|
@@ -1094,7 +1092,7 @@ describe('MenoFilter', () => {
|
|
|
1094
1092
|
filter.enableUrlSync();
|
|
1095
1093
|
filter.sort('title', 'desc');
|
|
1096
1094
|
|
|
1097
|
-
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]
|
|
1095
|
+
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]!;
|
|
1098
1096
|
// URLSearchParams encodes : as %3A
|
|
1099
1097
|
const decodedUrl = decodeURIComponent(lastCall[2] as string);
|
|
1100
1098
|
expect(decodedUrl).toContain('sort=title:desc');
|
|
@@ -1110,7 +1108,7 @@ describe('MenoFilter', () => {
|
|
|
1110
1108
|
filter.enableUrlSync();
|
|
1111
1109
|
filter.search('hello', ['title', 'category']);
|
|
1112
1110
|
|
|
1113
|
-
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]
|
|
1111
|
+
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]!;
|
|
1114
1112
|
// URLSearchParams encodes , as %2C
|
|
1115
1113
|
const decodedUrl = decodeURIComponent(lastCall[2] as string);
|
|
1116
1114
|
expect(decodedUrl).toContain('search=hello');
|
|
@@ -1132,7 +1130,7 @@ describe('MenoFilter', () => {
|
|
|
1132
1130
|
filter.enableUrlSync();
|
|
1133
1131
|
filter.setPage(3);
|
|
1134
1132
|
|
|
1135
|
-
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]
|
|
1133
|
+
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]!;
|
|
1136
1134
|
expect(lastCall[2]).toContain('page=3');
|
|
1137
1135
|
});
|
|
1138
1136
|
|
|
@@ -1149,7 +1147,7 @@ describe('MenoFilter', () => {
|
|
|
1149
1147
|
filter.enableUrlSync();
|
|
1150
1148
|
filter.filter({ views: { $gt: 100, $lte: 200 } });
|
|
1151
1149
|
|
|
1152
|
-
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]
|
|
1150
|
+
const lastCall = mockHistory.replaceState.mock.calls[mockHistory.replaceState.mock.calls.length - 1]!;
|
|
1153
1151
|
// URLSearchParams encodes $ as %24
|
|
1154
1152
|
const decodedUrl = decodeURIComponent(lastCall[2] as string);
|
|
1155
1153
|
expect(decodedUrl).toContain('filter.views.$gt=100');
|
|
@@ -562,7 +562,9 @@ export class MenoFilter {
|
|
|
562
562
|
const value = item[field];
|
|
563
563
|
if (value !== undefined && value !== null) {
|
|
564
564
|
if (Array.isArray(value)) {
|
|
565
|
-
value.forEach((v) =>
|
|
565
|
+
value.forEach((v) => {
|
|
566
|
+
values.add(v);
|
|
567
|
+
});
|
|
566
568
|
} else {
|
|
567
569
|
values.add(value);
|
|
568
570
|
}
|
|
@@ -669,12 +671,12 @@ export class MenoFilter {
|
|
|
669
671
|
case 'number': {
|
|
670
672
|
if (typeof value === 'number') return value;
|
|
671
673
|
const num = parseFloat(String(value));
|
|
672
|
-
return isNaN(num) ? value : num;
|
|
674
|
+
return Number.isNaN(num) ? value : num;
|
|
673
675
|
}
|
|
674
676
|
case 'date': {
|
|
675
677
|
if (value instanceof Date) return value.getTime();
|
|
676
678
|
const time = new Date(String(value)).getTime();
|
|
677
|
-
return isNaN(time) ? value : time;
|
|
679
|
+
return Number.isNaN(time) ? value : time;
|
|
678
680
|
}
|
|
679
681
|
case 'boolean':
|
|
680
682
|
return value === true || value === 'true' || value === '1';
|
|
@@ -797,9 +799,7 @@ export class MenoFilter {
|
|
|
797
799
|
}
|
|
798
800
|
|
|
799
801
|
const queryString = params.toString();
|
|
800
|
-
const url = queryString
|
|
801
|
-
? `${window.location.pathname}?${queryString}`
|
|
802
|
-
: window.location.pathname;
|
|
802
|
+
const url = queryString ? `${window.location.pathname}?${queryString}` : window.location.pathname;
|
|
803
803
|
|
|
804
804
|
if (this.urlMode === 'push') {
|
|
805
805
|
history.pushState(null, '', url);
|
|
@@ -825,6 +825,7 @@ export class MenoFilter {
|
|
|
825
825
|
const parts = key.split('.');
|
|
826
826
|
const field = parts[1];
|
|
827
827
|
const op = parts[2]; // Optional operator
|
|
828
|
+
if (field === undefined) continue;
|
|
828
829
|
|
|
829
830
|
if (op) {
|
|
830
831
|
// Operator: filter.price.$gt=100
|
|
@@ -845,7 +846,7 @@ export class MenoFilter {
|
|
|
845
846
|
// Parse sort
|
|
846
847
|
const sortParam = params.get('sort');
|
|
847
848
|
if (sortParam) {
|
|
848
|
-
const [field, order = 'asc'] = sortParam.split(':');
|
|
849
|
+
const [field = '', order = 'asc'] = sortParam.split(':');
|
|
849
850
|
this.sortConfig = { field, order: order as 'asc' | 'desc' };
|
|
850
851
|
}
|
|
851
852
|
|
|
@@ -863,7 +864,7 @@ export class MenoFilter {
|
|
|
863
864
|
const pageParam = params.get('page');
|
|
864
865
|
if (pageParam) {
|
|
865
866
|
const page = parseInt(pageParam, 10);
|
|
866
|
-
if (!isNaN(page) && page > 0) {
|
|
867
|
+
if (!Number.isNaN(page) && page > 0) {
|
|
867
868
|
this.currentPage = page;
|
|
868
869
|
}
|
|
869
870
|
}
|
|
@@ -872,7 +873,7 @@ export class MenoFilter {
|
|
|
872
873
|
const perPageParam = params.get('perPage');
|
|
873
874
|
if (perPageParam) {
|
|
874
875
|
const perPage = parseInt(perPageParam, 10);
|
|
875
|
-
if (!isNaN(perPage) && perPage > 0) {
|
|
876
|
+
if (!Number.isNaN(perPage) && perPage > 0) {
|
|
876
877
|
this.perPage = perPage;
|
|
877
878
|
}
|
|
878
879
|
}
|
|
@@ -1082,17 +1083,14 @@ export class MenoFilter {
|
|
|
1082
1083
|
|
|
1083
1084
|
// Apply OR criteria
|
|
1084
1085
|
if (this.orCriteria.length > 0) {
|
|
1085
|
-
result = result.filter((item) =>
|
|
1086
|
-
this.orCriteria.some((criteria) => this.matchesCriteria(item, criteria))
|
|
1087
|
-
);
|
|
1086
|
+
result = result.filter((item) => this.orCriteria.some((criteria) => this.matchesCriteria(item, criteria)));
|
|
1088
1087
|
}
|
|
1089
1088
|
|
|
1090
1089
|
// Apply search
|
|
1091
1090
|
if (this.searchQuery) {
|
|
1092
1091
|
const query = this.searchQuery;
|
|
1093
1092
|
result = result.filter((item) => {
|
|
1094
|
-
const fieldsToSearch =
|
|
1095
|
-
this.searchFields.length > 0 ? this.searchFields : Object.keys(item);
|
|
1093
|
+
const fieldsToSearch = this.searchFields.length > 0 ? this.searchFields : Object.keys(item);
|
|
1096
1094
|
return fieldsToSearch.some((field) => {
|
|
1097
1095
|
const value = item[field];
|
|
1098
1096
|
if (typeof value !== 'string') return false;
|
|
@@ -1259,13 +1257,14 @@ export class MenoFilter {
|
|
|
1259
1257
|
case '$nin':
|
|
1260
1258
|
return Array.isArray(opValue) ? !opValue.includes(itemValue) : true;
|
|
1261
1259
|
|
|
1262
|
-
case '$empty':
|
|
1260
|
+
case '$empty': {
|
|
1263
1261
|
const isEmpty =
|
|
1264
1262
|
itemValue === undefined ||
|
|
1265
1263
|
itemValue === null ||
|
|
1266
1264
|
itemValue === '' ||
|
|
1267
1265
|
(Array.isArray(itemValue) && itemValue.length === 0);
|
|
1268
1266
|
return opValue ? isEmpty : !isEmpty;
|
|
1267
|
+
}
|
|
1269
1268
|
|
|
1270
1269
|
default:
|
|
1271
1270
|
console.warn(`MenoFilter: Unknown operator "${op}"`);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* to MenoFilter instances via data attributes.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { MenoFilter } from './MenoFilter';
|
|
8
|
+
import type { MenoFilter } from './MenoFilter';
|
|
9
9
|
import { ATTR } from './constants';
|
|
10
10
|
import type { FilterInstance, FilterMode } from './types';
|
|
11
11
|
|
|
@@ -42,12 +42,7 @@ function getFilterMode(element: HTMLElement): FilterMode | null {
|
|
|
42
42
|
* Handle button click in multi-select mode
|
|
43
43
|
* Toggles value in $in array
|
|
44
44
|
*/
|
|
45
|
-
function handleMultiButtonClick(
|
|
46
|
-
filter: MenoFilter,
|
|
47
|
-
field: string,
|
|
48
|
-
value: string,
|
|
49
|
-
currentValue: unknown
|
|
50
|
-
): void {
|
|
45
|
+
function handleMultiButtonClick(filter: MenoFilter, field: string, value: string, currentValue: unknown): void {
|
|
51
46
|
// Get current values as array
|
|
52
47
|
let values: string[] = [];
|
|
53
48
|
if (currentValue !== undefined) {
|
|
@@ -87,9 +82,7 @@ export function bindFilterControls(instance: FilterInstance): void {
|
|
|
87
82
|
const { wrapper, filter, cleanup } = instance;
|
|
88
83
|
|
|
89
84
|
// Filter buttons
|
|
90
|
-
const filterButtons = wrapper.querySelectorAll<HTMLElement>(
|
|
91
|
-
`[${ATTR.FILTER_FIELD}][${ATTR.FILTER_VALUE}]`
|
|
92
|
-
);
|
|
85
|
+
const filterButtons = wrapper.querySelectorAll<HTMLElement>(`[${ATTR.FILTER_FIELD}][${ATTR.FILTER_VALUE}]`);
|
|
93
86
|
|
|
94
87
|
for (const btn of filterButtons) {
|
|
95
88
|
if (btn.tagName === 'INPUT') continue; // Handle inputs separately
|
|
@@ -118,7 +111,6 @@ export function bindFilterControls(instance: FilterInstance): void {
|
|
|
118
111
|
filter.addFilter(field, value);
|
|
119
112
|
}
|
|
120
113
|
}
|
|
121
|
-
|
|
122
114
|
};
|
|
123
115
|
|
|
124
116
|
btn.addEventListener('click', handler);
|
|
@@ -126,9 +118,7 @@ export function bindFilterControls(instance: FilterInstance): void {
|
|
|
126
118
|
}
|
|
127
119
|
|
|
128
120
|
// Filter checkboxes (allow multiple selections with OR logic)
|
|
129
|
-
const filterCheckboxes = wrapper.querySelectorAll<HTMLInputElement>(
|
|
130
|
-
`input[type="checkbox"][${ATTR.FILTER_FIELD}]`
|
|
131
|
-
);
|
|
121
|
+
const filterCheckboxes = wrapper.querySelectorAll<HTMLInputElement>(`input[type="checkbox"][${ATTR.FILTER_FIELD}]`);
|
|
132
122
|
|
|
133
123
|
for (const checkbox of filterCheckboxes) {
|
|
134
124
|
const field = checkbox.getAttribute(ATTR.FILTER_FIELD)!;
|
|
@@ -139,7 +129,7 @@ export function bindFilterControls(instance: FilterInstance): void {
|
|
|
139
129
|
// Single mode: uncheck other checkboxes in the same field
|
|
140
130
|
if (mode === 'single' && checkbox.checked) {
|
|
141
131
|
const siblings = wrapper.querySelectorAll<HTMLInputElement>(
|
|
142
|
-
`input[type="checkbox"][${ATTR.FILTER_FIELD}="${field}"]
|
|
132
|
+
`input[type="checkbox"][${ATTR.FILTER_FIELD}="${field}"]`,
|
|
143
133
|
);
|
|
144
134
|
for (const sibling of siblings) {
|
|
145
135
|
if (sibling !== checkbox) {
|
|
@@ -156,9 +146,7 @@ export function bindFilterControls(instance: FilterInstance): void {
|
|
|
156
146
|
}
|
|
157
147
|
|
|
158
148
|
// Filter selects
|
|
159
|
-
const filterSelects = wrapper.querySelectorAll<HTMLSelectElement>(
|
|
160
|
-
`select[${ATTR.FILTER_FIELD}]`
|
|
161
|
-
);
|
|
149
|
+
const filterSelects = wrapper.querySelectorAll<HTMLSelectElement>(`select[${ATTR.FILTER_FIELD}]`);
|
|
162
150
|
|
|
163
151
|
for (const select of filterSelects) {
|
|
164
152
|
const field = select.getAttribute(ATTR.FILTER_FIELD)!;
|
|
@@ -177,9 +165,7 @@ export function bindFilterControls(instance: FilterInstance): void {
|
|
|
177
165
|
}
|
|
178
166
|
|
|
179
167
|
// Filter radio buttons
|
|
180
|
-
const filterRadios = wrapper.querySelectorAll<HTMLInputElement>(
|
|
181
|
-
`input[type="radio"][${ATTR.FILTER_FIELD}]`
|
|
182
|
-
);
|
|
168
|
+
const filterRadios = wrapper.querySelectorAll<HTMLInputElement>(`input[type="radio"][${ATTR.FILTER_FIELD}]`);
|
|
183
169
|
|
|
184
170
|
for (const radio of filterRadios) {
|
|
185
171
|
const field = radio.getAttribute(ATTR.FILTER_FIELD)!;
|
|
@@ -203,18 +189,12 @@ export function bindFilterControls(instance: FilterInstance): void {
|
|
|
203
189
|
/**
|
|
204
190
|
* Update filters based on checked checkboxes for a field
|
|
205
191
|
*/
|
|
206
|
-
function updateCheckboxFilters(
|
|
207
|
-
wrapper: HTMLElement,
|
|
208
|
-
filter: MenoFilter,
|
|
209
|
-
field: string
|
|
210
|
-
): void {
|
|
192
|
+
function updateCheckboxFilters(wrapper: HTMLElement, filter: MenoFilter, field: string): void {
|
|
211
193
|
const checkboxes = wrapper.querySelectorAll<HTMLInputElement>(
|
|
212
|
-
`input[type="checkbox"][${ATTR.FILTER_FIELD}="${field}"]:checked
|
|
194
|
+
`input[type="checkbox"][${ATTR.FILTER_FIELD}="${field}"]:checked`,
|
|
213
195
|
);
|
|
214
196
|
|
|
215
|
-
const values = Array.from(checkboxes).map(
|
|
216
|
-
(cb) => cb.getAttribute(ATTR.FILTER_VALUE) || cb.value
|
|
217
|
-
);
|
|
197
|
+
const values = Array.from(checkboxes).map((cb) => cb.getAttribute(ATTR.FILTER_VALUE) || cb.value);
|
|
218
198
|
|
|
219
199
|
if (values.length === 0) {
|
|
220
200
|
filter.removeFilter(field);
|
|
@@ -311,7 +291,7 @@ export function bindSortControls(instance: FilterInstance): void {
|
|
|
311
291
|
}
|
|
312
292
|
|
|
313
293
|
// Parse "field:order" format
|
|
314
|
-
const [field, order = 'asc'] = value.split(':');
|
|
294
|
+
const [field = '', order = 'asc'] = value.split(':');
|
|
315
295
|
filter.sort(field, order as 'asc' | 'desc');
|
|
316
296
|
};
|
|
317
297
|
|
|
@@ -363,17 +343,13 @@ export function bindActionControls(instance: FilterInstance): void {
|
|
|
363
343
|
*/
|
|
364
344
|
export function resetFormControls(wrapper: HTMLElement): void {
|
|
365
345
|
// Reset checkboxes
|
|
366
|
-
const checkboxes = wrapper.querySelectorAll<HTMLInputElement>(
|
|
367
|
-
`input[type="checkbox"][${ATTR.FILTER_FIELD}]`
|
|
368
|
-
);
|
|
346
|
+
const checkboxes = wrapper.querySelectorAll<HTMLInputElement>(`input[type="checkbox"][${ATTR.FILTER_FIELD}]`);
|
|
369
347
|
for (const cb of checkboxes) {
|
|
370
348
|
cb.checked = false;
|
|
371
349
|
}
|
|
372
350
|
|
|
373
351
|
// Reset selects
|
|
374
|
-
const selects = wrapper.querySelectorAll<HTMLSelectElement>(
|
|
375
|
-
`select[${ATTR.FILTER_FIELD}]`
|
|
376
|
-
);
|
|
352
|
+
const selects = wrapper.querySelectorAll<HTMLSelectElement>(`select[${ATTR.FILTER_FIELD}]`);
|
|
377
353
|
for (const select of selects) {
|
|
378
354
|
select.selectedIndex = 0;
|
|
379
355
|
}
|
|
@@ -421,12 +397,13 @@ export function bindPaginationControls(instance: FilterInstance): void {
|
|
|
421
397
|
case 'last':
|
|
422
398
|
filter.setPage(filter.getPageInfo().total);
|
|
423
399
|
break;
|
|
424
|
-
default:
|
|
400
|
+
default: {
|
|
425
401
|
// Numeric page
|
|
426
402
|
const page = parseInt(action || '1', 10);
|
|
427
|
-
if (!isNaN(page)) {
|
|
403
|
+
if (!Number.isNaN(page)) {
|
|
428
404
|
filter.setPage(page);
|
|
429
405
|
}
|
|
406
|
+
}
|
|
430
407
|
}
|
|
431
408
|
};
|
|
432
409
|
|
|
@@ -435,14 +412,12 @@ export function bindPaginationControls(instance: FilterInstance): void {
|
|
|
435
412
|
}
|
|
436
413
|
|
|
437
414
|
// Per-page select
|
|
438
|
-
const perPageSelects = wrapper.querySelectorAll<HTMLSelectElement>(
|
|
439
|
-
`[${ATTR.PER_PAGE_SELECT}]`
|
|
440
|
-
);
|
|
415
|
+
const perPageSelects = wrapper.querySelectorAll<HTMLSelectElement>(`[${ATTR.PER_PAGE_SELECT}]`);
|
|
441
416
|
|
|
442
417
|
for (const select of perPageSelects) {
|
|
443
418
|
const handler = () => {
|
|
444
419
|
const perPage = parseInt(select.value, 10);
|
|
445
|
-
if (!isNaN(perPage) && perPage > 0) {
|
|
420
|
+
if (!Number.isNaN(perPage) && perPage > 0) {
|
|
446
421
|
filter.setPerPage(perPage);
|
|
447
422
|
}
|
|
448
423
|
};
|
|
@@ -79,7 +79,7 @@ async function initFilterInstance(wrapper: HTMLElement, collection: string): Pro
|
|
|
79
79
|
const thresholdAttr = searchInput.getAttribute(ATTR.SEARCH_THRESHOLD);
|
|
80
80
|
if (thresholdAttr) {
|
|
81
81
|
const parsed = parseFloat(thresholdAttr);
|
|
82
|
-
if (!isNaN(parsed)) {
|
|
82
|
+
if (!Number.isNaN(parsed)) {
|
|
83
83
|
fuzzyThreshold = parsed;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
@@ -136,7 +136,7 @@ async function initFilterInstance(wrapper: HTMLElement, collection: string): Pro
|
|
|
136
136
|
cleanup.push(
|
|
137
137
|
filter.watch(() => {
|
|
138
138
|
updateUI(instance);
|
|
139
|
-
})
|
|
139
|
+
}),
|
|
140
140
|
);
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -165,7 +165,7 @@ function extractItemTemplate(wrapper: HTMLElement): {
|
|
|
165
165
|
const itemTemplate = emittedTemplate.innerHTML.trim();
|
|
166
166
|
// Detect itemAs from template variables (e.g., {{post.title}} → "post")
|
|
167
167
|
const match = itemTemplate.match(/\{\{(\w+)\./);
|
|
168
|
-
if (match) itemAs = match[1];
|
|
168
|
+
if (match && match[1] !== undefined) itemAs = match[1];
|
|
169
169
|
|
|
170
170
|
// Store SSR'd items by their data-id for potential reuse
|
|
171
171
|
for (const child of Array.from(listEl.children) as HTMLElement[]) {
|
|
@@ -184,7 +184,7 @@ function extractItemTemplate(wrapper: HTMLElement): {
|
|
|
184
184
|
if (userTemplate) {
|
|
185
185
|
const itemTemplate = userTemplate.innerHTML.trim();
|
|
186
186
|
const match = itemTemplate.match(/\{\{(\w+)\./);
|
|
187
|
-
if (match) itemAs = match[1];
|
|
187
|
+
if (match && match[1] !== undefined) itemAs = match[1];
|
|
188
188
|
return { itemTemplate, ssrItems, itemAs };
|
|
189
189
|
}
|
|
190
190
|
|