@mdfriday/foundry 0.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/LICENSE +15 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/application/ssg.d.ts +9 -0
- package/dist/internal/application/ssg.d.ts.map +1 -0
- package/dist/internal/application/ssg.js +476 -0
- package/dist/internal/application/ssg.js.map +1 -0
- package/dist/internal/application/test-ssg.d.ts +8 -0
- package/dist/internal/application/test-ssg.d.ts.map +1 -0
- package/dist/internal/application/test-ssg.js +27 -0
- package/dist/internal/application/test-ssg.js.map +1 -0
- package/dist/internal/domain/config/entity/config.d.ts +64 -0
- package/dist/internal/domain/config/entity/config.d.ts.map +1 -0
- package/dist/internal/domain/config/entity/config.js +94 -0
- package/dist/internal/domain/config/entity/config.js.map +1 -0
- package/dist/internal/domain/config/entity/dir.d.ts +13 -0
- package/dist/internal/domain/config/entity/dir.d.ts.map +1 -0
- package/dist/internal/domain/config/entity/dir.js +33 -0
- package/dist/internal/domain/config/entity/dir.js.map +1 -0
- package/dist/internal/domain/config/entity/language.d.ts +71 -0
- package/dist/internal/domain/config/entity/language.d.ts.map +1 -0
- package/dist/internal/domain/config/entity/language.js +135 -0
- package/dist/internal/domain/config/entity/language.js.map +1 -0
- package/dist/internal/domain/config/entity/module.d.ts +53 -0
- package/dist/internal/domain/config/entity/module.d.ts.map +1 -0
- package/dist/internal/domain/config/entity/module.js +82 -0
- package/dist/internal/domain/config/entity/module.js.map +1 -0
- package/dist/internal/domain/config/entity/root.d.ts +58 -0
- package/dist/internal/domain/config/entity/root.d.ts.map +1 -0
- package/dist/internal/domain/config/entity/root.js +105 -0
- package/dist/internal/domain/config/entity/root.js.map +1 -0
- package/dist/internal/domain/config/entity/service.d.ts +57 -0
- package/dist/internal/domain/config/entity/service.d.ts.map +1 -0
- package/dist/internal/domain/config/entity/service.js +88 -0
- package/dist/internal/domain/config/entity/service.js.map +1 -0
- package/dist/internal/domain/config/entity/taxonomy.d.ts +59 -0
- package/dist/internal/domain/config/entity/taxonomy.d.ts.map +1 -0
- package/dist/internal/domain/config/entity/taxonomy.js +101 -0
- package/dist/internal/domain/config/entity/taxonomy.js.map +1 -0
- package/dist/internal/domain/config/factory/config.d.ts +7 -0
- package/dist/internal/domain/config/factory/config.d.ts.map +1 -0
- package/dist/internal/domain/config/factory/config.js +92 -0
- package/dist/internal/domain/config/factory/config.js.map +1 -0
- package/dist/internal/domain/config/factory/loader.d.ts +45 -0
- package/dist/internal/domain/config/factory/loader.d.ts.map +1 -0
- package/dist/internal/domain/config/factory/loader.js +204 -0
- package/dist/internal/domain/config/factory/loader.js.map +1 -0
- package/dist/internal/domain/config/factory/provider.d.ts +36 -0
- package/dist/internal/domain/config/factory/provider.d.ts.map +1 -0
- package/dist/internal/domain/config/factory/provider.js +206 -0
- package/dist/internal/domain/config/factory/provider.js.map +1 -0
- package/dist/internal/domain/config/factory/sourcedescriptor.d.ts +19 -0
- package/dist/internal/domain/config/factory/sourcedescriptor.d.ts.map +1 -0
- package/dist/internal/domain/config/factory/sourcedescriptor.js +25 -0
- package/dist/internal/domain/config/factory/sourcedescriptor.js.map +1 -0
- package/dist/internal/domain/config/index.d.ts +14 -0
- package/dist/internal/domain/config/index.d.ts.map +1 -0
- package/dist/internal/domain/config/index.js +48 -0
- package/dist/internal/domain/config/index.js.map +1 -0
- package/dist/internal/domain/config/type.d.ts +145 -0
- package/dist/internal/domain/config/type.d.ts.map +1 -0
- package/dist/internal/domain/config/type.js +23 -0
- package/dist/internal/domain/config/type.js.map +1 -0
- package/dist/internal/domain/config/vo/language.d.ts +14 -0
- package/dist/internal/domain/config/vo/language.d.ts.map +1 -0
- package/dist/internal/domain/config/vo/language.js +57 -0
- package/dist/internal/domain/config/vo/language.js.map +1 -0
- package/dist/internal/domain/config/vo/module.d.ts +14 -0
- package/dist/internal/domain/config/vo/module.d.ts.map +1 -0
- package/dist/internal/domain/config/vo/module.js +44 -0
- package/dist/internal/domain/config/vo/module.js.map +1 -0
- package/dist/internal/domain/config/vo/root.d.ts +10 -0
- package/dist/internal/domain/config/vo/root.d.ts.map +1 -0
- package/dist/internal/domain/config/vo/root.js +71 -0
- package/dist/internal/domain/config/vo/root.js.map +1 -0
- package/dist/internal/domain/config/vo/service.d.ts +10 -0
- package/dist/internal/domain/config/vo/service.d.ts.map +1 -0
- package/dist/internal/domain/config/vo/service.js +73 -0
- package/dist/internal/domain/config/vo/service.js.map +1 -0
- package/dist/internal/domain/config/vo/taxonomy.d.ts +18 -0
- package/dist/internal/domain/config/vo/taxonomy.d.ts.map +1 -0
- package/dist/internal/domain/config/vo/taxonomy.js +68 -0
- package/dist/internal/domain/config/vo/taxonomy.js.map +1 -0
- package/dist/internal/domain/content/entity/content.d.ts +47 -0
- package/dist/internal/domain/content/entity/content.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/content.js +281 -0
- package/dist/internal/domain/content/entity/content.js.map +1 -0
- package/dist/internal/domain/content/entity/converter.d.ts +11 -0
- package/dist/internal/domain/content/entity/converter.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/converter.js +22 -0
- package/dist/internal/domain/content/entity/converter.js.map +1 -0
- package/dist/internal/domain/content/entity/index.d.ts +5 -0
- package/dist/internal/domain/content/entity/index.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/index.js +21 -0
- package/dist/internal/domain/content/entity/index.js.map +1 -0
- package/dist/internal/domain/content/entity/page.d.ts +90 -0
- package/dist/internal/domain/content/entity/page.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/page.js +336 -0
- package/dist/internal/domain/content/entity/page.js.map +1 -0
- package/dist/internal/domain/content/entity/pagebuilder.d.ts +145 -0
- package/dist/internal/domain/content/entity/pagebuilder.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/pagebuilder.js +521 -0
- package/dist/internal/domain/content/entity/pagebuilder.js.map +1 -0
- package/dist/internal/domain/content/entity/pagecollector.d.ts +17 -0
- package/dist/internal/domain/content/entity/pagecollector.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/pagecollector.js +108 -0
- package/dist/internal/domain/content/entity/pagecollector.js.map +1 -0
- package/dist/internal/domain/content/entity/pagecontent.d.ts +37 -0
- package/dist/internal/domain/content/entity/pagecontent.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/pagecontent.js +70 -0
- package/dist/internal/domain/content/entity/pagecontent.js.map +1 -0
- package/dist/internal/domain/content/entity/pagelayout.d.ts +11 -0
- package/dist/internal/domain/content/entity/pagelayout.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/pagelayout.js +73 -0
- package/dist/internal/domain/content/entity/pagelayout.js.map +1 -0
- package/dist/internal/domain/content/entity/pagemap.d.ts +143 -0
- package/dist/internal/domain/content/entity/pagemap.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/pagemap.js +497 -0
- package/dist/internal/domain/content/entity/pagemap.js.map +1 -0
- package/dist/internal/domain/content/entity/pagemeta.d.ts +18 -0
- package/dist/internal/domain/content/entity/pagemeta.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/pagemeta.js +50 -0
- package/dist/internal/domain/content/entity/pagemeta.js.map +1 -0
- package/dist/internal/domain/content/entity/pageoutput.d.ts +15 -0
- package/dist/internal/domain/content/entity/pageoutput.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/pageoutput.js +133 -0
- package/dist/internal/domain/content/entity/pageoutput.js.map +1 -0
- package/dist/internal/domain/content/entity/pagesource.d.ts +62 -0
- package/dist/internal/domain/content/entity/pagesource.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/pagesource.js +168 -0
- package/dist/internal/domain/content/entity/pagesource.js.map +1 -0
- package/dist/internal/domain/content/entity/pagetrees.d.ts +70 -0
- package/dist/internal/domain/content/entity/pagetrees.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/pagetrees.js +249 -0
- package/dist/internal/domain/content/entity/pagetrees.js.map +1 -0
- package/dist/internal/domain/content/entity/paginator.d.ts +69 -0
- package/dist/internal/domain/content/entity/paginator.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/paginator.js +245 -0
- package/dist/internal/domain/content/entity/paginator.js.map +1 -0
- package/dist/internal/domain/content/entity/section.d.ts +34 -0
- package/dist/internal/domain/content/entity/section.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/section.js +120 -0
- package/dist/internal/domain/content/entity/section.js.map +1 -0
- package/dist/internal/domain/content/entity/shifter.d.ts +10 -0
- package/dist/internal/domain/content/entity/shifter.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/shifter.js +36 -0
- package/dist/internal/domain/content/entity/shifter.js.map +1 -0
- package/dist/internal/domain/content/entity/shifterpage.d.ts +7 -0
- package/dist/internal/domain/content/entity/shifterpage.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/shifterpage.js +20 -0
- package/dist/internal/domain/content/entity/shifterpage.js.map +1 -0
- package/dist/internal/domain/content/entity/shifterpagesource.d.ts +7 -0
- package/dist/internal/domain/content/entity/shifterpagesource.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/shifterpagesource.js +21 -0
- package/dist/internal/domain/content/entity/shifterpagesource.js.map +1 -0
- package/dist/internal/domain/content/entity/shortcode.d.ts +76 -0
- package/dist/internal/domain/content/entity/shortcode.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/shortcode.js +156 -0
- package/dist/internal/domain/content/entity/shortcode.js.map +1 -0
- package/dist/internal/domain/content/entity/standalone.d.ts +22 -0
- package/dist/internal/domain/content/entity/standalone.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/standalone.js +38 -0
- package/dist/internal/domain/content/entity/standalone.js.map +1 -0
- package/dist/internal/domain/content/entity/taxonomy.d.ts +30 -0
- package/dist/internal/domain/content/entity/taxonomy.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/taxonomy.js +131 -0
- package/dist/internal/domain/content/entity/taxonomy.js.map +1 -0
- package/dist/internal/domain/content/entity/term.d.ts +17 -0
- package/dist/internal/domain/content/entity/term.d.ts.map +1 -0
- package/dist/internal/domain/content/entity/term.js +146 -0
- package/dist/internal/domain/content/entity/term.js.map +1 -0
- package/dist/internal/domain/content/factory/hub.d.ts +3 -0
- package/dist/internal/domain/content/factory/hub.d.ts.map +1 -0
- package/dist/internal/domain/content/factory/hub.js +26 -0
- package/dist/internal/domain/content/factory/hub.js.map +1 -0
- package/dist/internal/domain/content/index.d.ts +18 -0
- package/dist/internal/domain/content/index.d.ts.map +1 -0
- package/dist/internal/domain/content/index.js +37 -0
- package/dist/internal/domain/content/index.js.map +1 -0
- package/dist/internal/domain/content/type.d.ts +237 -0
- package/dist/internal/domain/content/type.d.ts.map +1 -0
- package/dist/internal/domain/content/type.js +16 -0
- package/dist/internal/domain/content/type.js.map +1 -0
- package/dist/internal/domain/content/vo/classifier.d.ts +40 -0
- package/dist/internal/domain/content/vo/classifier.d.ts.map +1 -0
- package/dist/internal/domain/content/vo/classifier.js +109 -0
- package/dist/internal/domain/content/vo/classifier.js.map +1 -0
- package/dist/internal/domain/content/vo/fileinfo.d.ts +46 -0
- package/dist/internal/domain/content/vo/fileinfo.d.ts.map +1 -0
- package/dist/internal/domain/content/vo/fileinfo.js +220 -0
- package/dist/internal/domain/content/vo/fileinfo.js.map +1 -0
- package/dist/internal/domain/content/vo/frontmatter.d.ts +62 -0
- package/dist/internal/domain/content/vo/frontmatter.d.ts.map +1 -0
- package/dist/internal/domain/content/vo/frontmatter.js +224 -0
- package/dist/internal/domain/content/vo/frontmatter.js.map +1 -0
- package/dist/internal/domain/content/vo/identity.d.ts +13 -0
- package/dist/internal/domain/content/vo/identity.d.ts.map +1 -0
- package/dist/internal/domain/content/vo/identity.js +27 -0
- package/dist/internal/domain/content/vo/identity.js.map +1 -0
- package/dist/internal/domain/content/vo/kind.d.ts +14 -0
- package/dist/internal/domain/content/vo/kind.d.ts.map +1 -0
- package/dist/internal/domain/content/vo/kind.js +52 -0
- package/dist/internal/domain/content/vo/kind.js.map +1 -0
- package/dist/internal/domain/content/vo/sort.d.ts +18 -0
- package/dist/internal/domain/content/vo/sort.d.ts.map +1 -0
- package/dist/internal/domain/content/vo/sort.js +147 -0
- package/dist/internal/domain/content/vo/sort.js.map +1 -0
- package/dist/internal/domain/fs/entity/basefs.d.ts +48 -0
- package/dist/internal/domain/fs/entity/basefs.d.ts.map +1 -0
- package/dist/internal/domain/fs/entity/basefs.js +191 -0
- package/dist/internal/domain/fs/entity/basefs.js.map +1 -0
- package/dist/internal/domain/fs/entity/fs.d.ts +49 -0
- package/dist/internal/domain/fs/entity/fs.d.ts.map +1 -0
- package/dist/internal/domain/fs/entity/fs.js +97 -0
- package/dist/internal/domain/fs/entity/fs.js.map +1 -0
- package/dist/internal/domain/fs/entity/originfs.d.ts +17 -0
- package/dist/internal/domain/fs/entity/originfs.d.ts.map +1 -0
- package/dist/internal/domain/fs/entity/originfs.js +27 -0
- package/dist/internal/domain/fs/entity/originfs.js.map +1 -0
- package/dist/internal/domain/fs/entity/overlaydir.d.ts +93 -0
- package/dist/internal/domain/fs/entity/overlaydir.d.ts.map +1 -0
- package/dist/internal/domain/fs/entity/overlaydir.js +249 -0
- package/dist/internal/domain/fs/entity/overlaydir.js.map +1 -0
- package/dist/internal/domain/fs/entity/overlayfs.d.ts +113 -0
- package/dist/internal/domain/fs/entity/overlayfs.d.ts.map +1 -0
- package/dist/internal/domain/fs/entity/overlayfs.js +310 -0
- package/dist/internal/domain/fs/entity/overlayfs.js.map +1 -0
- package/dist/internal/domain/fs/entity/service.d.ts +23 -0
- package/dist/internal/domain/fs/entity/service.d.ts.map +1 -0
- package/dist/internal/domain/fs/entity/service.js +35 -0
- package/dist/internal/domain/fs/entity/service.js.map +1 -0
- package/dist/internal/domain/fs/factory/fs.d.ts +13 -0
- package/dist/internal/domain/fs/factory/fs.d.ts.map +1 -0
- package/dist/internal/domain/fs/factory/fs.js +21 -0
- package/dist/internal/domain/fs/factory/fs.js.map +1 -0
- package/dist/internal/domain/fs/index.d.ts +24 -0
- package/dist/internal/domain/fs/index.d.ts.map +1 -0
- package/dist/internal/domain/fs/index.js +104 -0
- package/dist/internal/domain/fs/index.js.map +1 -0
- package/dist/internal/domain/fs/type.d.ts +219 -0
- package/dist/internal/domain/fs/type.d.ts.map +1 -0
- package/dist/internal/domain/fs/type.js +53 -0
- package/dist/internal/domain/fs/type.js.map +1 -0
- package/dist/internal/domain/fs/vo/dir.d.ts +63 -0
- package/dist/internal/domain/fs/vo/dir.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/dir.js +99 -0
- package/dist/internal/domain/fs/vo/dir.js.map +1 -0
- package/dist/internal/domain/fs/vo/file.d.ts +73 -0
- package/dist/internal/domain/fs/vo/file.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/file.js +197 -0
- package/dist/internal/domain/fs/vo/file.js.map +1 -0
- package/dist/internal/domain/fs/vo/fileinfo.d.ts +48 -0
- package/dist/internal/domain/fs/vo/fileinfo.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/fileinfo.js +108 -0
- package/dist/internal/domain/fs/vo/fileinfo.js.map +1 -0
- package/dist/internal/domain/fs/vo/filemeta.d.ts +73 -0
- package/dist/internal/domain/fs/vo/filemeta.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/filemeta.js +124 -0
- package/dist/internal/domain/fs/vo/filemeta.js.map +1 -0
- package/dist/internal/domain/fs/vo/filesystemscollector.d.ts +47 -0
- package/dist/internal/domain/fs/vo/filesystemscollector.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/filesystemscollector.js +169 -0
- package/dist/internal/domain/fs/vo/filesystemscollector.js.map +1 -0
- package/dist/internal/domain/fs/vo/filevitural.d.ts +12 -0
- package/dist/internal/domain/fs/vo/filevitural.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/filevitural.js +137 -0
- package/dist/internal/domain/fs/vo/filevitural.js.map +1 -0
- package/dist/internal/domain/fs/vo/osfs.d.ts +78 -0
- package/dist/internal/domain/fs/vo/osfs.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/osfs.js +296 -0
- package/dist/internal/domain/fs/vo/osfs.js.map +1 -0
- package/dist/internal/domain/fs/vo/overlay-factory.d.ts +13 -0
- package/dist/internal/domain/fs/vo/overlay-factory.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/overlay-factory.js +60 -0
- package/dist/internal/domain/fs/vo/overlay-factory.js.map +1 -0
- package/dist/internal/domain/fs/vo/overlayfs-factory.d.ts +72 -0
- package/dist/internal/domain/fs/vo/overlayfs-factory.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/overlayfs-factory.js +125 -0
- package/dist/internal/domain/fs/vo/overlayfs-factory.js.map +1 -0
- package/dist/internal/domain/fs/vo/overlayoptions.d.ts +69 -0
- package/dist/internal/domain/fs/vo/overlayoptions.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/overlayoptions.js +138 -0
- package/dist/internal/domain/fs/vo/overlayoptions.js.map +1 -0
- package/dist/internal/domain/fs/vo/static-copier.d.ts +37 -0
- package/dist/internal/domain/fs/vo/static-copier.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/static-copier.js +179 -0
- package/dist/internal/domain/fs/vo/static-copier.js.map +1 -0
- package/dist/internal/domain/fs/vo/walkway.d.ts +38 -0
- package/dist/internal/domain/fs/vo/walkway.d.ts.map +1 -0
- package/dist/internal/domain/fs/vo/walkway.js +219 -0
- package/dist/internal/domain/fs/vo/walkway.js.map +1 -0
- package/dist/internal/domain/markdown/entity/markdown.d.ts +79 -0
- package/dist/internal/domain/markdown/entity/markdown.d.ts.map +1 -0
- package/dist/internal/domain/markdown/entity/markdown.js +385 -0
- package/dist/internal/domain/markdown/entity/markdown.js.map +1 -0
- package/dist/internal/domain/markdown/examples/obsidian-example.d.ts +79 -0
- package/dist/internal/domain/markdown/examples/obsidian-example.d.ts.map +1 -0
- package/dist/internal/domain/markdown/examples/obsidian-example.js +302 -0
- package/dist/internal/domain/markdown/examples/obsidian-example.js.map +1 -0
- package/dist/internal/domain/markdown/examples/shortcode.d.ts +43 -0
- package/dist/internal/domain/markdown/examples/shortcode.d.ts.map +1 -0
- package/dist/internal/domain/markdown/examples/shortcode.js +99 -0
- package/dist/internal/domain/markdown/examples/shortcode.js.map +1 -0
- package/dist/internal/domain/markdown/factory/markdown.d.ts +39 -0
- package/dist/internal/domain/markdown/factory/markdown.d.ts.map +1 -0
- package/dist/internal/domain/markdown/factory/markdown.js +78 -0
- package/dist/internal/domain/markdown/factory/markdown.js.map +1 -0
- package/dist/internal/domain/markdown/index.d.ts +15 -0
- package/dist/internal/domain/markdown/index.d.ts.map +1 -0
- package/dist/internal/domain/markdown/index.js +38 -0
- package/dist/internal/domain/markdown/index.js.map +1 -0
- package/dist/internal/domain/markdown/test/external-adapter.test.d.ts +2 -0
- package/dist/internal/domain/markdown/test/external-adapter.test.d.ts.map +1 -0
- package/dist/internal/domain/markdown/test/external-adapter.test.js +150 -0
- package/dist/internal/domain/markdown/test/external-adapter.test.js.map +1 -0
- package/dist/internal/domain/markdown/test/markdown.test.d.ts +2 -0
- package/dist/internal/domain/markdown/test/markdown.test.d.ts.map +1 -0
- package/dist/internal/domain/markdown/test/markdown.test.js +88 -0
- package/dist/internal/domain/markdown/test/markdown.test.js.map +1 -0
- package/dist/internal/domain/markdown/type.d.ts +363 -0
- package/dist/internal/domain/markdown/type.d.ts.map +1 -0
- package/dist/internal/domain/markdown/type.js +19 -0
- package/dist/internal/domain/markdown/type.js.map +1 -0
- package/dist/internal/domain/markdown/vo/config.d.ts +139 -0
- package/dist/internal/domain/markdown/vo/config.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/config.js +89 -0
- package/dist/internal/domain/markdown/vo/config.js.map +1 -0
- package/dist/internal/domain/markdown/vo/content.d.ts +149 -0
- package/dist/internal/domain/markdown/vo/content.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/content.js +370 -0
- package/dist/internal/domain/markdown/vo/content.js.map +1 -0
- package/dist/internal/domain/markdown/vo/context.d.ts +45 -0
- package/dist/internal/domain/markdown/vo/context.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/context.js +112 -0
- package/dist/internal/domain/markdown/vo/context.js.map +1 -0
- package/dist/internal/domain/markdown/vo/externaladapter.d.ts +63 -0
- package/dist/internal/domain/markdown/vo/externaladapter.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/externaladapter.js +194 -0
- package/dist/internal/domain/markdown/vo/externaladapter.js.map +1 -0
- package/dist/internal/domain/markdown/vo/highlight.d.ts +46 -0
- package/dist/internal/domain/markdown/vo/highlight.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/highlight.js +159 -0
- package/dist/internal/domain/markdown/vo/highlight.js.map +1 -0
- package/dist/internal/domain/markdown/vo/markdownit.d.ts +33 -0
- package/dist/internal/domain/markdown/vo/markdownit.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/markdownit.js +175 -0
- package/dist/internal/domain/markdown/vo/markdownit.js.map +1 -0
- package/dist/internal/domain/markdown/vo/pageparser.d.ts +20 -0
- package/dist/internal/domain/markdown/vo/pageparser.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/pageparser.js +87 -0
- package/dist/internal/domain/markdown/vo/pageparser.js.map +1 -0
- package/dist/internal/domain/markdown/vo/parseinfo.d.ts +63 -0
- package/dist/internal/domain/markdown/vo/parseinfo.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/parseinfo.js +132 -0
- package/dist/internal/domain/markdown/vo/parseinfo.js.map +1 -0
- package/dist/internal/domain/markdown/vo/parserresult.d.ts +82 -0
- package/dist/internal/domain/markdown/vo/parserresult.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/parserresult.js +214 -0
- package/dist/internal/domain/markdown/vo/parserresult.js.map +1 -0
- package/dist/internal/domain/markdown/vo/shortcode.d.ts +68 -0
- package/dist/internal/domain/markdown/vo/shortcode.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/shortcode.js +298 -0
- package/dist/internal/domain/markdown/vo/shortcode.js.map +1 -0
- package/dist/internal/domain/markdown/vo/tableofcontents.d.ts +82 -0
- package/dist/internal/domain/markdown/vo/tableofcontents.d.ts.map +1 -0
- package/dist/internal/domain/markdown/vo/tableofcontents.js +234 -0
- package/dist/internal/domain/markdown/vo/tableofcontents.js.map +1 -0
- package/dist/internal/domain/module/entity/lang.d.ts +20 -0
- package/dist/internal/domain/module/entity/lang.d.ts.map +1 -0
- package/dist/internal/domain/module/entity/lang.js +38 -0
- package/dist/internal/domain/module/entity/lang.js.map +1 -0
- package/dist/internal/domain/module/entity/module.d.ts +87 -0
- package/dist/internal/domain/module/entity/module.d.ts.map +1 -0
- package/dist/internal/domain/module/entity/module.js +343 -0
- package/dist/internal/domain/module/entity/module.js.map +1 -0
- package/dist/internal/domain/module/factory/module.d.ts +7 -0
- package/dist/internal/domain/module/factory/module.d.ts.map +1 -0
- package/dist/internal/domain/module/factory/module.js +31 -0
- package/dist/internal/domain/module/factory/module.js.map +1 -0
- package/dist/internal/domain/module/index.d.ts +10 -0
- package/dist/internal/domain/module/index.d.ts.map +1 -0
- package/dist/internal/domain/module/index.js +72 -0
- package/dist/internal/domain/module/index.js.map +1 -0
- package/dist/internal/domain/module/type.d.ts +160 -0
- package/dist/internal/domain/module/type.d.ts.map +1 -0
- package/dist/internal/domain/module/type.js +50 -0
- package/dist/internal/domain/module/type.js.map +1 -0
- package/dist/internal/domain/module/vo/cache.d.ts +81 -0
- package/dist/internal/domain/module/vo/cache.d.ts.map +1 -0
- package/dist/internal/domain/module/vo/cache.js +282 -0
- package/dist/internal/domain/module/vo/cache.js.map +1 -0
- package/dist/internal/domain/module/vo/httpclient.d.ts +101 -0
- package/dist/internal/domain/module/vo/httpclient.d.ts.map +1 -0
- package/dist/internal/domain/module/vo/httpclient.js +442 -0
- package/dist/internal/domain/module/vo/httpclient.js.map +1 -0
- package/dist/internal/domain/module/vo/module.d.ts +129 -0
- package/dist/internal/domain/module/vo/module.d.ts.map +1 -0
- package/dist/internal/domain/module/vo/module.js +271 -0
- package/dist/internal/domain/module/vo/module.js.map +1 -0
- package/dist/internal/domain/module/vo/mount.d.ts +59 -0
- package/dist/internal/domain/module/vo/mount.d.ts.map +1 -0
- package/dist/internal/domain/module/vo/mount.js +134 -0
- package/dist/internal/domain/module/vo/mount.js.map +1 -0
- package/dist/internal/domain/module/vo/zipextractor.d.ts +57 -0
- package/dist/internal/domain/module/vo/zipextractor.d.ts.map +1 -0
- package/dist/internal/domain/module/vo/zipextractor.js +267 -0
- package/dist/internal/domain/module/vo/zipextractor.js.map +1 -0
- package/dist/internal/domain/paths/entity/path.d.ts +86 -0
- package/dist/internal/domain/paths/entity/path.d.ts.map +1 -0
- package/dist/internal/domain/paths/entity/path.js +450 -0
- package/dist/internal/domain/paths/entity/path.js.map +1 -0
- package/dist/internal/domain/paths/factory/pathfactory.d.ts +140 -0
- package/dist/internal/domain/paths/factory/pathfactory.d.ts.map +1 -0
- package/dist/internal/domain/paths/factory/pathfactory.js +246 -0
- package/dist/internal/domain/paths/factory/pathfactory.js.map +1 -0
- package/dist/internal/domain/paths/index.d.ts +44 -0
- package/dist/internal/domain/paths/index.d.ts.map +1 -0
- package/dist/internal/domain/paths/index.js +94 -0
- package/dist/internal/domain/paths/index.js.map +1 -0
- package/dist/internal/domain/paths/test/factory.test.d.ts +2 -0
- package/dist/internal/domain/paths/test/factory.test.d.ts.map +1 -0
- package/dist/internal/domain/paths/test/factory.test.js +352 -0
- package/dist/internal/domain/paths/test/factory.test.js.map +1 -0
- package/dist/internal/domain/paths/test/integration.test.d.ts +2 -0
- package/dist/internal/domain/paths/test/integration.test.d.ts.map +1 -0
- package/dist/internal/domain/paths/test/integration.test.js +328 -0
- package/dist/internal/domain/paths/test/integration.test.js.map +1 -0
- package/dist/internal/domain/paths/test/pathoperations.test.d.ts +2 -0
- package/dist/internal/domain/paths/test/pathoperations.test.d.ts.map +1 -0
- package/dist/internal/domain/paths/test/pathoperations.test.js +413 -0
- package/dist/internal/domain/paths/test/pathoperations.test.js.map +1 -0
- package/dist/internal/domain/paths/test/pathparser.test.d.ts +2 -0
- package/dist/internal/domain/paths/test/pathparser.test.d.ts.map +1 -0
- package/dist/internal/domain/paths/test/pathparser.test.js +403 -0
- package/dist/internal/domain/paths/test/pathparser.test.js.map +1 -0
- package/dist/internal/domain/paths/type.d.ts +284 -0
- package/dist/internal/domain/paths/type.d.ts.map +1 -0
- package/dist/internal/domain/paths/type.js +65 -0
- package/dist/internal/domain/paths/type.js.map +1 -0
- package/dist/internal/domain/paths/vo/pathcomponents.d.ts +148 -0
- package/dist/internal/domain/paths/vo/pathcomponents.d.ts.map +1 -0
- package/dist/internal/domain/paths/vo/pathcomponents.js +223 -0
- package/dist/internal/domain/paths/vo/pathcomponents.js.map +1 -0
- package/dist/internal/domain/paths/vo/pathparser.d.ts +130 -0
- package/dist/internal/domain/paths/vo/pathparser.d.ts.map +1 -0
- package/dist/internal/domain/paths/vo/pathparser.js +354 -0
- package/dist/internal/domain/paths/vo/pathparser.js.map +1 -0
- package/dist/internal/domain/prompt/entity/collector.d.ts +88 -0
- package/dist/internal/domain/prompt/entity/collector.d.ts.map +1 -0
- package/dist/internal/domain/prompt/entity/collector.js +255 -0
- package/dist/internal/domain/prompt/entity/collector.js.map +1 -0
- package/dist/internal/domain/prompt/entity/finder.d.ts +88 -0
- package/dist/internal/domain/prompt/entity/finder.d.ts.map +1 -0
- package/dist/internal/domain/prompt/entity/finder.js +293 -0
- package/dist/internal/domain/prompt/entity/finder.js.map +1 -0
- package/dist/internal/domain/prompt/entity/hub.d.ts +112 -0
- package/dist/internal/domain/prompt/entity/hub.d.ts.map +1 -0
- package/dist/internal/domain/prompt/entity/hub.js +259 -0
- package/dist/internal/domain/prompt/entity/hub.js.map +1 -0
- package/dist/internal/domain/prompt/entity/prompt.d.ts +133 -0
- package/dist/internal/domain/prompt/entity/prompt.d.ts.map +1 -0
- package/dist/internal/domain/prompt/entity/prompt.js +237 -0
- package/dist/internal/domain/prompt/entity/prompt.js.map +1 -0
- package/dist/internal/domain/prompt/factory/prompt.d.ts +55 -0
- package/dist/internal/domain/prompt/factory/prompt.d.ts.map +1 -0
- package/dist/internal/domain/prompt/factory/prompt.js +212 -0
- package/dist/internal/domain/prompt/factory/prompt.js.map +1 -0
- package/dist/internal/domain/prompt/index.d.ts +10 -0
- package/dist/internal/domain/prompt/index.d.ts.map +1 -0
- package/dist/internal/domain/prompt/index.js +72 -0
- package/dist/internal/domain/prompt/index.js.map +1 -0
- package/dist/internal/domain/prompt/type.d.ts +180 -0
- package/dist/internal/domain/prompt/type.d.ts.map +1 -0
- package/dist/internal/domain/prompt/type.js +23 -0
- package/dist/internal/domain/prompt/type.js.map +1 -0
- package/dist/internal/domain/prompt/vo/file.d.ts +103 -0
- package/dist/internal/domain/prompt/vo/file.d.ts.map +1 -0
- package/dist/internal/domain/prompt/vo/file.js +265 -0
- package/dist/internal/domain/prompt/vo/file.js.map +1 -0
- package/dist/internal/domain/prompt/vo/rule.d.ts +139 -0
- package/dist/internal/domain/prompt/vo/rule.d.ts.map +1 -0
- package/dist/internal/domain/prompt/vo/rule.js +268 -0
- package/dist/internal/domain/prompt/vo/rule.js.map +1 -0
- package/dist/internal/domain/resources/entity/integrity.d.ts +13 -0
- package/dist/internal/domain/resources/entity/integrity.d.ts.map +1 -0
- package/dist/internal/domain/resources/entity/integrity.js +113 -0
- package/dist/internal/domain/resources/entity/integrity.js.map +1 -0
- package/dist/internal/domain/resources/entity/minifier.d.ts +20 -0
- package/dist/internal/domain/resources/entity/minifier.d.ts.map +1 -0
- package/dist/internal/domain/resources/entity/minifier.js +118 -0
- package/dist/internal/domain/resources/entity/minifier.js.map +1 -0
- package/dist/internal/domain/resources/entity/publisher.d.ts +44 -0
- package/dist/internal/domain/resources/entity/publisher.d.ts.map +1 -0
- package/dist/internal/domain/resources/entity/publisher.js +159 -0
- package/dist/internal/domain/resources/entity/publisher.js.map +1 -0
- package/dist/internal/domain/resources/entity/resource.d.ts +62 -0
- package/dist/internal/domain/resources/entity/resource.d.ts.map +1 -0
- package/dist/internal/domain/resources/entity/resource.js +362 -0
- package/dist/internal/domain/resources/entity/resource.js.map +1 -0
- package/dist/internal/domain/resources/entity/resources.d.ts +64 -0
- package/dist/internal/domain/resources/entity/resources.d.ts.map +1 -0
- package/dist/internal/domain/resources/entity/resources.js +344 -0
- package/dist/internal/domain/resources/entity/resources.js.map +1 -0
- package/dist/internal/domain/resources/entity/template.d.ts +11 -0
- package/dist/internal/domain/resources/entity/template.d.ts.map +1 -0
- package/dist/internal/domain/resources/entity/template.js +135 -0
- package/dist/internal/domain/resources/entity/template.js.map +1 -0
- package/dist/internal/domain/resources/factory/resource.d.ts +8 -0
- package/dist/internal/domain/resources/factory/resource.d.ts.map +1 -0
- package/dist/internal/domain/resources/factory/resource.js +12 -0
- package/dist/internal/domain/resources/factory/resource.js.map +1 -0
- package/dist/internal/domain/resources/index.d.ts +11 -0
- package/dist/internal/domain/resources/index.d.ts.map +1 -0
- package/dist/internal/domain/resources/index.js +42 -0
- package/dist/internal/domain/resources/index.js.map +1 -0
- package/dist/internal/domain/resources/type.d.ts +84 -0
- package/dist/internal/domain/resources/type.d.ts.map +1 -0
- package/dist/internal/domain/resources/type.js +3 -0
- package/dist/internal/domain/resources/type.js.map +1 -0
- package/dist/internal/domain/resources/valueobject/resourcemetadata.d.ts +14 -0
- package/dist/internal/domain/resources/valueobject/resourcemetadata.d.ts.map +1 -0
- package/dist/internal/domain/resources/valueobject/resourcemetadata.js +23 -0
- package/dist/internal/domain/resources/valueobject/resourcemetadata.js.map +1 -0
- package/dist/internal/domain/resources/valueobject/resourcepaths.d.ts +21 -0
- package/dist/internal/domain/resources/valueobject/resourcepaths.d.ts.map +1 -0
- package/dist/internal/domain/resources/valueobject/resourcepaths.js +136 -0
- package/dist/internal/domain/resources/valueobject/resourcepaths.js.map +1 -0
- package/dist/internal/domain/resources/valueobject/resourcepaths.test.d.ts +2 -0
- package/dist/internal/domain/resources/valueobject/resourcepaths.test.d.ts.map +1 -0
- package/dist/internal/domain/resources/valueobject/resourcepaths.test.js +53 -0
- package/dist/internal/domain/resources/valueobject/resourcepaths.test.js.map +1 -0
- package/dist/internal/domain/resources/valueobject/transformation.d.ts +11 -0
- package/dist/internal/domain/resources/valueobject/transformation.d.ts.map +1 -0
- package/dist/internal/domain/resources/valueobject/transformation.js +41 -0
- package/dist/internal/domain/resources/valueobject/transformation.js.map +1 -0
- package/dist/internal/domain/site/entity/language.d.ts +82 -0
- package/dist/internal/domain/site/entity/language.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/language.js +168 -0
- package/dist/internal/domain/site/entity/language.js.map +1 -0
- package/dist/internal/domain/site/entity/menu-builder.d.ts +52 -0
- package/dist/internal/domain/site/entity/menu-builder.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/menu-builder.js +192 -0
- package/dist/internal/domain/site/entity/menu-builder.js.map +1 -0
- package/dist/internal/domain/site/entity/navigation.d.ts +30 -0
- package/dist/internal/domain/site/entity/navigation.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/navigation.js +94 -0
- package/dist/internal/domain/site/entity/navigation.js.map +1 -0
- package/dist/internal/domain/site/entity/page.d.ts +169 -0
- package/dist/internal/domain/site/entity/page.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/page.js +578 -0
- package/dist/internal/domain/site/entity/page.js.map +1 -0
- package/dist/internal/domain/site/entity/pager.d.ts +36 -0
- package/dist/internal/domain/site/entity/pager.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/pager.js +104 -0
- package/dist/internal/domain/site/entity/pager.js.map +1 -0
- package/dist/internal/domain/site/entity/publisher.d.ts +39 -0
- package/dist/internal/domain/site/entity/publisher.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/publisher.js +138 -0
- package/dist/internal/domain/site/entity/publisher.js.map +1 -0
- package/dist/internal/domain/site/entity/ref.d.ts +41 -0
- package/dist/internal/domain/site/entity/ref.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/ref.js +129 -0
- package/dist/internal/domain/site/entity/ref.js.map +1 -0
- package/dist/internal/domain/site/entity/site.d.ts +173 -0
- package/dist/internal/domain/site/entity/site.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/site.js +405 -0
- package/dist/internal/domain/site/entity/site.js.map +1 -0
- package/dist/internal/domain/site/entity/taxonomies-builder.d.ts +66 -0
- package/dist/internal/domain/site/entity/taxonomies-builder.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/taxonomies-builder.js +243 -0
- package/dist/internal/domain/site/entity/taxonomies-builder.js.map +1 -0
- package/dist/internal/domain/site/entity/url.d.ts +24 -0
- package/dist/internal/domain/site/entity/url.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/url.js +205 -0
- package/dist/internal/domain/site/entity/url.js.map +1 -0
- package/dist/internal/domain/site/entity/url.test.d.ts +2 -0
- package/dist/internal/domain/site/entity/url.test.d.ts.map +1 -0
- package/dist/internal/domain/site/entity/url.test.js +98 -0
- package/dist/internal/domain/site/entity/url.test.js.map +1 -0
- package/dist/internal/domain/site/factory/navigation-factory.d.ts +16 -0
- package/dist/internal/domain/site/factory/navigation-factory.d.ts.map +1 -0
- package/dist/internal/domain/site/factory/navigation-factory.js +45 -0
- package/dist/internal/domain/site/factory/navigation-factory.js.map +1 -0
- package/dist/internal/domain/site/factory/site.d.ts +8 -0
- package/dist/internal/domain/site/factory/site.d.ts.map +1 -0
- package/dist/internal/domain/site/factory/site.js +59 -0
- package/dist/internal/domain/site/factory/site.js.map +1 -0
- package/dist/internal/domain/site/type.d.ts +248 -0
- package/dist/internal/domain/site/type.d.ts.map +1 -0
- package/dist/internal/domain/site/type.js +3 -0
- package/dist/internal/domain/site/type.js.map +1 -0
- package/dist/internal/domain/site/valueobject/author.d.ts +23 -0
- package/dist/internal/domain/site/valueobject/author.d.ts.map +1 -0
- package/dist/internal/domain/site/valueobject/author.js +35 -0
- package/dist/internal/domain/site/valueobject/author.js.map +1 -0
- package/dist/internal/domain/site/valueobject/baseurl.d.ts +64 -0
- package/dist/internal/domain/site/valueobject/baseurl.d.ts.map +1 -0
- package/dist/internal/domain/site/valueobject/baseurl.js +200 -0
- package/dist/internal/domain/site/valueobject/baseurl.js.map +1 -0
- package/dist/internal/domain/site/valueobject/baseurl.test.d.ts +2 -0
- package/dist/internal/domain/site/valueobject/baseurl.test.d.ts.map +1 -0
- package/dist/internal/domain/site/valueobject/baseurl.test.js +138 -0
- package/dist/internal/domain/site/valueobject/baseurl.test.js.map +1 -0
- package/dist/internal/domain/site/valueobject/menu.d.ts +179 -0
- package/dist/internal/domain/site/valueobject/menu.d.ts.map +1 -0
- package/dist/internal/domain/site/valueobject/menu.js +319 -0
- package/dist/internal/domain/site/valueobject/menu.js.map +1 -0
- package/dist/internal/domain/site/valueobject/version.d.ts +22 -0
- package/dist/internal/domain/site/valueobject/version.d.ts.map +1 -0
- package/dist/internal/domain/site/valueobject/version.js +34 -0
- package/dist/internal/domain/site/valueobject/version.js.map +1 -0
- package/dist/internal/domain/template/entity/executor.d.ts +48 -0
- package/dist/internal/domain/template/entity/executor.d.ts.map +1 -0
- package/dist/internal/domain/template/entity/executor.js +147 -0
- package/dist/internal/domain/template/entity/executor.js.map +1 -0
- package/dist/internal/domain/template/entity/lookup.d.ts +85 -0
- package/dist/internal/domain/template/entity/lookup.d.ts.map +1 -0
- package/dist/internal/domain/template/entity/lookup.js +192 -0
- package/dist/internal/domain/template/entity/lookup.js.map +1 -0
- package/dist/internal/domain/template/entity/parser.d.ts +54 -0
- package/dist/internal/domain/template/entity/parser.d.ts.map +1 -0
- package/dist/internal/domain/template/entity/parser.js +314 -0
- package/dist/internal/domain/template/entity/parser.js.map +1 -0
- package/dist/internal/domain/template/entity/template.d.ts +137 -0
- package/dist/internal/domain/template/entity/template.d.ts.map +1 -0
- package/dist/internal/domain/template/entity/template.js +394 -0
- package/dist/internal/domain/template/entity/template.js.map +1 -0
- package/dist/internal/domain/template/factory/template.d.ts +93 -0
- package/dist/internal/domain/template/factory/template.d.ts.map +1 -0
- package/dist/internal/domain/template/factory/template.js +206 -0
- package/dist/internal/domain/template/factory/template.js.map +1 -0
- package/dist/internal/domain/template/index.d.ts +11 -0
- package/dist/internal/domain/template/index.d.ts.map +1 -0
- package/dist/internal/domain/template/index.js +74 -0
- package/dist/internal/domain/template/index.js.map +1 -0
- package/dist/internal/domain/template/type.d.ts +281 -0
- package/dist/internal/domain/template/type.d.ts.map +1 -0
- package/dist/internal/domain/template/type.js +34 -0
- package/dist/internal/domain/template/type.js.map +1 -0
- package/dist/internal/domain/template/vo/baseof.d.ts +70 -0
- package/dist/internal/domain/template/vo/baseof.d.ts.map +1 -0
- package/dist/internal/domain/template/vo/baseof.js +184 -0
- package/dist/internal/domain/template/vo/baseof.js.map +1 -0
- package/dist/internal/domain/template/vo/info.d.ts +58 -0
- package/dist/internal/domain/template/vo/info.d.ts.map +1 -0
- package/dist/internal/domain/template/vo/info.js +149 -0
- package/dist/internal/domain/template/vo/info.js.map +1 -0
- package/dist/internal/domain/template/vo/namespace.d.ts +130 -0
- package/dist/internal/domain/template/vo/namespace.d.ts.map +1 -0
- package/dist/internal/domain/template/vo/namespace.js +256 -0
- package/dist/internal/domain/template/vo/namespace.js.map +1 -0
- package/dist/internal/domain/template/vo/registry.d.ts +161 -0
- package/dist/internal/domain/template/vo/registry.d.ts.map +1 -0
- package/dist/internal/domain/template/vo/registry.js +1950 -0
- package/dist/internal/domain/template/vo/registry.js.map +1 -0
- package/dist/pkg/cast/cast.d.ts +6 -0
- package/dist/pkg/cast/cast.d.ts.map +1 -0
- package/dist/pkg/cast/cast.js +42 -0
- package/dist/pkg/cast/cast.js.map +1 -0
- package/dist/pkg/cast/index.d.ts +2 -0
- package/dist/pkg/cast/index.d.ts.map +1 -0
- package/dist/pkg/cast/index.js +18 -0
- package/dist/pkg/cast/index.js.map +1 -0
- package/dist/pkg/doctree/dimensions.d.ts +19 -0
- package/dist/pkg/doctree/dimensions.d.ts.map +1 -0
- package/dist/pkg/doctree/dimensions.js +49 -0
- package/dist/pkg/doctree/dimensions.js.map +1 -0
- package/dist/pkg/doctree/doctree.test.d.ts +2 -0
- package/dist/pkg/doctree/doctree.test.d.ts.map +1 -0
- package/dist/pkg/doctree/doctree.test.js +162 -0
- package/dist/pkg/doctree/doctree.test.js.map +1 -0
- package/dist/pkg/doctree/index.d.ts +6 -0
- package/dist/pkg/doctree/index.d.ts.map +1 -0
- package/dist/pkg/doctree/index.js +30 -0
- package/dist/pkg/doctree/index.js.map +1 -0
- package/dist/pkg/doctree/nodeshifttree.d.ts +83 -0
- package/dist/pkg/doctree/nodeshifttree.d.ts.map +1 -0
- package/dist/pkg/doctree/nodeshifttree.js +363 -0
- package/dist/pkg/doctree/nodeshifttree.js.map +1 -0
- package/dist/pkg/doctree/simpletree.d.ts +20 -0
- package/dist/pkg/doctree/simpletree.d.ts.map +1 -0
- package/dist/pkg/doctree/simpletree.js +116 -0
- package/dist/pkg/doctree/simpletree.js.map +1 -0
- package/dist/pkg/doctree/support.d.ts +61 -0
- package/dist/pkg/doctree/support.d.ts.map +1 -0
- package/dist/pkg/doctree/support.js +193 -0
- package/dist/pkg/doctree/support.js.map +1 -0
- package/dist/pkg/doctree/treeshifttree.d.ts +18 -0
- package/dist/pkg/doctree/treeshifttree.d.ts.map +1 -0
- package/dist/pkg/doctree/treeshifttree.js +81 -0
- package/dist/pkg/doctree/treeshifttree.js.map +1 -0
- package/dist/pkg/log/http.d.ts +26 -0
- package/dist/pkg/log/http.d.ts.map +1 -0
- package/dist/pkg/log/http.js +59 -0
- package/dist/pkg/log/http.js.map +1 -0
- package/dist/pkg/log/index.d.ts +17 -0
- package/dist/pkg/log/index.d.ts.map +1 -0
- package/dist/pkg/log/index.js +53 -0
- package/dist/pkg/log/index.js.map +1 -0
- package/dist/pkg/log/logger.d.ts +25 -0
- package/dist/pkg/log/logger.d.ts.map +1 -0
- package/dist/pkg/log/logger.js +183 -0
- package/dist/pkg/log/logger.js.map +1 -0
- package/dist/pkg/log/manager.d.ts +84 -0
- package/dist/pkg/log/manager.d.ts.map +1 -0
- package/dist/pkg/log/manager.js +152 -0
- package/dist/pkg/log/manager.js.map +1 -0
- package/dist/pkg/log/types.d.ts +33 -0
- package/dist/pkg/log/types.d.ts.map +1 -0
- package/dist/pkg/log/types.js +12 -0
- package/dist/pkg/log/types.js.map +1 -0
- package/dist/pkg/maps/scratch.d.ts +38 -0
- package/dist/pkg/maps/scratch.d.ts.map +1 -0
- package/dist/pkg/maps/scratch.js +89 -0
- package/dist/pkg/maps/scratch.js.map +1 -0
- package/dist/pkg/md/parser/item.d.ts +57 -0
- package/dist/pkg/md/parser/item.d.ts.map +1 -0
- package/dist/pkg/md/parser/item.js +181 -0
- package/dist/pkg/md/parser/item.js.map +1 -0
- package/dist/pkg/md/parser/item.test.d.ts +2 -0
- package/dist/pkg/md/parser/item.test.d.ts.map +1 -0
- package/dist/pkg/md/parser/item.test.js +81 -0
- package/dist/pkg/md/parser/item.test.js.map +1 -0
- package/dist/pkg/md/parser/pagelexer.d.ts +129 -0
- package/dist/pkg/md/parser/pagelexer.d.ts.map +1 -0
- package/dist/pkg/md/parser/pagelexer.js +1274 -0
- package/dist/pkg/md/parser/pagelexer.js.map +1 -0
- package/dist/pkg/md/parser/pageparser.d.ts +29 -0
- package/dist/pkg/md/parser/pageparser.d.ts.map +1 -0
- package/dist/pkg/md/parser/pageparser.js +177 -0
- package/dist/pkg/md/parser/pageparser.js.map +1 -0
- package/dist/pkg/md/parser/pageparser.shortcode.test.d.ts +2 -0
- package/dist/pkg/md/parser/pageparser.shortcode.test.d.ts.map +1 -0
- package/dist/pkg/md/parser/pageparser.shortcode.test.js +182 -0
- package/dist/pkg/md/parser/pageparser.shortcode.test.js.map +1 -0
- package/dist/pkg/md/parser/pageparser.test.d.ts +2 -0
- package/dist/pkg/md/parser/pageparser.test.d.ts.map +1 -0
- package/dist/pkg/md/parser/pageparser.test.js +97 -0
- package/dist/pkg/md/parser/pageparser.test.js.map +1 -0
- package/dist/pkg/md/parser/pageparser_intro.test.d.ts +2 -0
- package/dist/pkg/md/parser/pageparser_intro.test.d.ts.map +1 -0
- package/dist/pkg/md/parser/pageparser_intro.test.js +156 -0
- package/dist/pkg/md/parser/pageparser_intro.test.js.map +1 -0
- package/dist/pkg/media/buildin.d.ts +4 -0
- package/dist/pkg/media/buildin.d.ts.map +1 -0
- package/dist/pkg/media/buildin.js +23 -0
- package/dist/pkg/media/buildin.js.map +1 -0
- package/dist/pkg/media/type.d.ts +45 -0
- package/dist/pkg/media/type.d.ts.map +1 -0
- package/dist/pkg/media/type.js +49 -0
- package/dist/pkg/media/type.js.map +1 -0
- package/dist/pkg/paths/index.d.ts +14 -0
- package/dist/pkg/paths/index.d.ts.map +1 -0
- package/dist/pkg/paths/index.js +65 -0
- package/dist/pkg/paths/index.js.map +1 -0
- package/dist/pkg/radix/index.d.ts +2 -0
- package/dist/pkg/radix/index.d.ts.map +1 -0
- package/dist/pkg/radix/index.js +8 -0
- package/dist/pkg/radix/index.js.map +1 -0
- package/dist/pkg/radix/radix.d.ts +51 -0
- package/dist/pkg/radix/radix.d.ts.map +1 -0
- package/dist/pkg/radix/radix.js +488 -0
- package/dist/pkg/radix/radix.js.map +1 -0
- package/dist/pkg/radix/radix.test.d.ts +2 -0
- package/dist/pkg/radix/radix.test.d.ts.map +1 -0
- package/dist/pkg/radix/radix.test.js +350 -0
- package/dist/pkg/radix/radix.test.js.map +1 -0
- package/dist/pkg/string/index.d.ts +2 -0
- package/dist/pkg/string/index.d.ts.map +1 -0
- package/dist/pkg/string/index.js +18 -0
- package/dist/pkg/string/index.js.map +1 -0
- package/dist/pkg/string/string.d.ts +4 -0
- package/dist/pkg/string/string.d.ts.map +1 -0
- package/dist/pkg/string/string.js +10 -0
- package/dist/pkg/string/string.js.map +1 -0
- package/dist/pkg/text/index.d.ts +6 -0
- package/dist/pkg/text/index.d.ts.map +1 -0
- package/dist/pkg/text/index.js +11 -0
- package/dist/pkg/text/index.js.map +1 -0
- package/dist/pkg/types/index.d.ts +2 -0
- package/dist/pkg/types/index.d.ts.map +1 -0
- package/dist/pkg/types/index.js +18 -0
- package/dist/pkg/types/index.js.map +1 -0
- package/dist/pkg/types/types.d.ts +4 -0
- package/dist/pkg/types/types.d.ts.map +1 -0
- package/dist/pkg/types/types.js +19 -0
- package/dist/pkg/types/types.js.map +1 -0
- package/dist/tests/setup.d.ts +2 -0
- package/dist/tests/setup.d.ts.map +1 -0
- package/dist/tests/setup.js +3 -0
- package/dist/tests/setup.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,1950 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Template functions registry
|
|
4
|
+
* Centralized management of template functions following DDD principles
|
|
5
|
+
* TypeScript equivalent of Go's valueobject/nsreg.go
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.DefaultTemplateRegistry = void 0;
|
|
42
|
+
exports.newTemplateRegistry = newTemplateRegistry;
|
|
43
|
+
exports.createCoreFuncMap = createCoreFuncMap;
|
|
44
|
+
exports.createStandardFuncMap = createStandardFuncMap;
|
|
45
|
+
exports.updateEngineDependentFunctions = updateEngineDependentFunctions;
|
|
46
|
+
const log_1 = require("@pkg/log");
|
|
47
|
+
const crypto = __importStar(require("crypto"));
|
|
48
|
+
// Create domain-specific logger for template operations
|
|
49
|
+
const log = (0, log_1.getDomainLogger)('template', { component: 'registry' });
|
|
50
|
+
const engineDependentFunctions = [];
|
|
51
|
+
/**
|
|
52
|
+
* Partial function implementation that depends on TemplateEngine
|
|
53
|
+
*/
|
|
54
|
+
class PartialFunction {
|
|
55
|
+
constructor() {
|
|
56
|
+
this.engine = null;
|
|
57
|
+
this.execute = async (name, context) => {
|
|
58
|
+
if (!this.engine) {
|
|
59
|
+
log.error(`Partial function called but engine not set: ${name}`);
|
|
60
|
+
return `<!-- Partial function called but engine not ready: ${name} -->`;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
// Ensure name has partials/ prefix if not already present
|
|
64
|
+
const templateName = name.startsWith('partials/') ? name : `partials/${name}`;
|
|
65
|
+
// Execute partial synchronously using engine's internal components
|
|
66
|
+
return await this.executePartial(templateName, context);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
log.error(`Partial execution failed for "${name}":`, error);
|
|
70
|
+
return `<!-- Partial execution failed: ${name} - ${error.message} -->`;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
getFunctionName() {
|
|
75
|
+
return 'partial';
|
|
76
|
+
}
|
|
77
|
+
updateEngine(engine) {
|
|
78
|
+
this.engine = engine;
|
|
79
|
+
log.info('PartialFunction: Template engine updated');
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Execute partial synchronously by directly accessing template engine internals
|
|
83
|
+
*/
|
|
84
|
+
async executePartial(templateName, context) {
|
|
85
|
+
if (!this.engine) {
|
|
86
|
+
return `<!-- Template engine not available: ${templateName} -->`;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
// Use the new getPartial method which routes to PartialNamespace
|
|
90
|
+
const [templateObj, found, err] = await this.engine.getPartial(templateName);
|
|
91
|
+
if (err) {
|
|
92
|
+
log.error(`Error getting partial template:`, err);
|
|
93
|
+
return `<!-- Error getting partial template: ${templateName} - ${err.message} -->`;
|
|
94
|
+
}
|
|
95
|
+
if (!found || !templateObj) {
|
|
96
|
+
log.warn(`Template not found: ${templateName}`);
|
|
97
|
+
return `<!-- Template not found: ${templateName} -->`;
|
|
98
|
+
}
|
|
99
|
+
// Execute the template directly
|
|
100
|
+
const [result, execErr] = await templateObj.Execute(context);
|
|
101
|
+
if (execErr) {
|
|
102
|
+
log.error(`Template execution error:`, execErr);
|
|
103
|
+
return `<!-- Template execution error: ${templateName} - ${execErr.message} -->`;
|
|
104
|
+
}
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
log.error(`Sync partial execution failed:`, error);
|
|
109
|
+
return `<!-- Partial sync execution failed: ${templateName} - ${error.message} -->`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Template functions registry implementation
|
|
115
|
+
* Following DDD principles - encapsulates template function management logic
|
|
116
|
+
*/
|
|
117
|
+
class DefaultTemplateRegistry {
|
|
118
|
+
/**
|
|
119
|
+
* Register core template functions that don't require external services
|
|
120
|
+
* Equivalent to Go's RegisterNamespaces()
|
|
121
|
+
*/
|
|
122
|
+
registerCoreFunctions(funcMap) {
|
|
123
|
+
// Crypto functions
|
|
124
|
+
this.registerCryptoFunctions(funcMap);
|
|
125
|
+
// String manipulation functions
|
|
126
|
+
this.registerStringFunctions(funcMap);
|
|
127
|
+
// Math functions
|
|
128
|
+
this.registerMathFunctions(funcMap);
|
|
129
|
+
// Date/time functions
|
|
130
|
+
this.registerTimeFunctions(funcMap);
|
|
131
|
+
// Collection functions
|
|
132
|
+
this.registerCollectionFunctions(funcMap);
|
|
133
|
+
// Safe functions
|
|
134
|
+
this.registerSafeFunctions(funcMap);
|
|
135
|
+
// Reflect functions
|
|
136
|
+
this.registerReflectFunctions(funcMap);
|
|
137
|
+
// Format functions (printf, errorf, etc.)
|
|
138
|
+
this.registerFmtFunctions(funcMap);
|
|
139
|
+
// Path functions
|
|
140
|
+
this.registerPathFunctions(funcMap);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Register cryptographic hash functions
|
|
144
|
+
* Equivalent to Go's crypto packages
|
|
145
|
+
*/
|
|
146
|
+
registerCryptoFunctions(funcMap) {
|
|
147
|
+
// MD5 hash function
|
|
148
|
+
funcMap.set('md5', (input) => {
|
|
149
|
+
if (!input)
|
|
150
|
+
return '';
|
|
151
|
+
return crypto.createHash('md5').update(input).digest('hex');
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Register extended template functions that require external services
|
|
156
|
+
* Equivalent to Go's RegisterExtendedNamespaces()
|
|
157
|
+
*/
|
|
158
|
+
registerExtendedFunctions(funcMap, services) {
|
|
159
|
+
// URL functions - require URL service
|
|
160
|
+
this.registerURLFunctions(funcMap, services);
|
|
161
|
+
// Site functions - require site service
|
|
162
|
+
this.registerSiteFunctions(funcMap, services);
|
|
163
|
+
this.registerResourcesFunctions(funcMap, services);
|
|
164
|
+
// Hugo functions - require hugo info service
|
|
165
|
+
this.registerHugoFunctions(funcMap, services);
|
|
166
|
+
// Language functions - require language service
|
|
167
|
+
this.registerLanguageFunctions(funcMap, services);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Register all available functions with services
|
|
171
|
+
* This is the main entry point for function registration
|
|
172
|
+
*/
|
|
173
|
+
registerAllFunctions(funcMap, services) {
|
|
174
|
+
log.info('🔧 Registering all template functions...');
|
|
175
|
+
// Register core functions (no services required)
|
|
176
|
+
this.registerCoreFunctions(funcMap);
|
|
177
|
+
this.registerStringFunctions(funcMap);
|
|
178
|
+
this.registerMathFunctions(funcMap);
|
|
179
|
+
this.registerTimeFunctions(funcMap);
|
|
180
|
+
this.registerCollectionFunctions(funcMap);
|
|
181
|
+
// Register engine-dependent functions (with placeholder implementations)
|
|
182
|
+
this.registerEngineDependentFunctions(funcMap);
|
|
183
|
+
// Register service-based functions if services are provided
|
|
184
|
+
if (services) {
|
|
185
|
+
this.registerURLFunctions(funcMap, services);
|
|
186
|
+
this.registerExtendedFunctions(funcMap, services);
|
|
187
|
+
}
|
|
188
|
+
log.info(`✅ Registered ${funcMap.size} template functions`);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Register functions that depend on TemplateEngine
|
|
192
|
+
* These functions are registered with placeholder implementations initially
|
|
193
|
+
*/
|
|
194
|
+
registerEngineDependentFunctions(funcMap) {
|
|
195
|
+
log.info('🔧 Registering engine-dependent functions...');
|
|
196
|
+
// Register partial function
|
|
197
|
+
const partialFunction = new PartialFunction();
|
|
198
|
+
engineDependentFunctions.push(partialFunction);
|
|
199
|
+
funcMap.set(partialFunction.getFunctionName(), partialFunction.execute);
|
|
200
|
+
log.info(`✅ Registered ${engineDependentFunctions.length} engine-dependent functions`);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Register URL template functions using URLService
|
|
204
|
+
* Equivalent to Go's registerUrls()
|
|
205
|
+
*/
|
|
206
|
+
registerURLFunctions(funcMap, services) {
|
|
207
|
+
// URLs namespace functions
|
|
208
|
+
funcMap.set('urls', () => ({
|
|
209
|
+
// Parse parses raw URL string into a URL structure
|
|
210
|
+
Parse: (rawurl) => {
|
|
211
|
+
try {
|
|
212
|
+
const u = new URL(rawurl);
|
|
213
|
+
return {
|
|
214
|
+
Host: u.host,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return {
|
|
219
|
+
Host: '',
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
// JoinPath joins path elements into a single path
|
|
224
|
+
JoinPath: (...elements) => {
|
|
225
|
+
// Remove empty elements and handle trailing slashes
|
|
226
|
+
const cleanElements = elements
|
|
227
|
+
.filter(e => e !== '')
|
|
228
|
+
.map(e => e.replace(/^\/+|\/+$/g, ''));
|
|
229
|
+
return cleanElements.join('/');
|
|
230
|
+
},
|
|
231
|
+
// URLize returns a URL-like string from the given text
|
|
232
|
+
URLize: (text) => services.urlize(text),
|
|
233
|
+
// Abs returns an absolute URL string
|
|
234
|
+
Abs: (url) => services.absURL(url),
|
|
235
|
+
// Rel returns a relative URL string
|
|
236
|
+
Rel: (url) => services.relURL(url),
|
|
237
|
+
// AbsLangURL returns an absolute URL modified with the language prefix
|
|
238
|
+
AbsLangURL: (url) => services.absURL(url), // TODO: Add language support
|
|
239
|
+
// RelLangURL returns a relative URL modified with the language prefix
|
|
240
|
+
RelLangURL: (url) => services.relURL(url), // TODO: Add language support
|
|
241
|
+
// Sanitize returns a sanitized string of the URL
|
|
242
|
+
Sanitize: (url) => {
|
|
243
|
+
try {
|
|
244
|
+
const parsed = new URL(url);
|
|
245
|
+
return parsed.toString();
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
// If not a valid URL, at least remove dangerous characters
|
|
249
|
+
return url.replace(/[<>"'%{}|\\^`]/g, '');
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
// PathEscape escapes special characters in a URL path
|
|
253
|
+
PathEscape: (path) => {
|
|
254
|
+
return encodeURIComponent(path)
|
|
255
|
+
.replace(/%2F/g, '/') // Keep forward slashes
|
|
256
|
+
.replace(/[!'()*]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
257
|
+
},
|
|
258
|
+
// QueryEscape escapes special characters in a URL query
|
|
259
|
+
QueryEscape: (query) => {
|
|
260
|
+
return encodeURIComponent(query);
|
|
261
|
+
},
|
|
262
|
+
// QueryUnescape unescapes special characters in a URL query
|
|
263
|
+
QueryUnescape: (query) => {
|
|
264
|
+
try {
|
|
265
|
+
return decodeURIComponent(query);
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
return query;
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
// IsAbs reports whether the URL is absolute
|
|
272
|
+
IsAbs: (urlStr) => {
|
|
273
|
+
try {
|
|
274
|
+
const url = new URL(urlStr);
|
|
275
|
+
return url.protocol !== '';
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
// IsRelative reports whether the URL is relative
|
|
282
|
+
IsRelative: (urlStr) => {
|
|
283
|
+
try {
|
|
284
|
+
new URL(urlStr);
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
return true;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}));
|
|
292
|
+
// Individual URL functions for backward compatibility
|
|
293
|
+
funcMap.set('absURL', (input) => services.absURL(input));
|
|
294
|
+
funcMap.set('relURL', (input) => services.relURL(input));
|
|
295
|
+
funcMap.set('urlize', (input) => services.urlize(input));
|
|
296
|
+
// Reference functions
|
|
297
|
+
funcMap.set('relref', (page, ref) => {
|
|
298
|
+
// If ref starts with http:// or https://, return as is
|
|
299
|
+
if (/^https?:\/\//.test(ref)) {
|
|
300
|
+
return ref;
|
|
301
|
+
}
|
|
302
|
+
// Remove anchor if present and store it
|
|
303
|
+
let anchor = '';
|
|
304
|
+
const hashIndex = ref.indexOf('#');
|
|
305
|
+
if (hashIndex !== -1) {
|
|
306
|
+
anchor = ref.slice(hashIndex);
|
|
307
|
+
ref = ref.slice(0, hashIndex);
|
|
308
|
+
}
|
|
309
|
+
// Remove leading and trailing slashes
|
|
310
|
+
ref = ref.replace(/^\/+|\/+$/g, '');
|
|
311
|
+
// If it's a relative path starting with ./ or ../, use relURL
|
|
312
|
+
if (ref.startsWith('./') || ref.startsWith('../')) {
|
|
313
|
+
return services.relURL(ref + anchor);
|
|
314
|
+
}
|
|
315
|
+
// Handle absolute paths
|
|
316
|
+
if (ref.startsWith('/')) {
|
|
317
|
+
return services.relURL(ref + anchor);
|
|
318
|
+
}
|
|
319
|
+
// For other cases, treat as relative path
|
|
320
|
+
return services.relURL('/' + ref + anchor);
|
|
321
|
+
});
|
|
322
|
+
funcMap.set('ref', (page, ref) => {
|
|
323
|
+
// Similar to relref but returns absolute URL
|
|
324
|
+
// If ref starts with http:// or https://, return as is
|
|
325
|
+
if (/^https?:\/\//.test(ref)) {
|
|
326
|
+
return ref;
|
|
327
|
+
}
|
|
328
|
+
// Remove anchor if present and store it
|
|
329
|
+
let anchor = '';
|
|
330
|
+
const hashIndex = ref.indexOf('#');
|
|
331
|
+
if (hashIndex !== -1) {
|
|
332
|
+
anchor = ref.slice(hashIndex);
|
|
333
|
+
ref = ref.slice(0, hashIndex);
|
|
334
|
+
}
|
|
335
|
+
// Remove leading and trailing slashes
|
|
336
|
+
ref = ref.replace(/^\/+|\/+$/g, '');
|
|
337
|
+
// If it's a relative path starting with ./ or ../, use absURL
|
|
338
|
+
if (ref.startsWith('./') || ref.startsWith('../')) {
|
|
339
|
+
return services.absURL(ref + anchor);
|
|
340
|
+
}
|
|
341
|
+
// Handle absolute paths
|
|
342
|
+
if (ref.startsWith('/')) {
|
|
343
|
+
return services.absURL(ref + anchor);
|
|
344
|
+
}
|
|
345
|
+
// For other cases, treat as relative path
|
|
346
|
+
return services.absURL('/' + ref + anchor);
|
|
347
|
+
});
|
|
348
|
+
// Language-aware URL functions
|
|
349
|
+
funcMap.set('absLangURL', (input) => {
|
|
350
|
+
// For now, delegate to absURL - can be enhanced for multi-language support
|
|
351
|
+
return services.absURL(input);
|
|
352
|
+
});
|
|
353
|
+
funcMap.set('relLangURL', (input) => {
|
|
354
|
+
// For now, delegate to relURL - can be enhanced for multi-language support
|
|
355
|
+
return services.relURL(input);
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Register site template functions using SiteService
|
|
360
|
+
* Equivalent to Go's registerSite()
|
|
361
|
+
*/
|
|
362
|
+
registerSiteFunctions(funcMap, services) {
|
|
363
|
+
// Site global object - register as a function that returns the site data
|
|
364
|
+
funcMap.set('Site', () => ({
|
|
365
|
+
Title: services.title(),
|
|
366
|
+
BaseURL: services.baseURL(),
|
|
367
|
+
Params: services.params(),
|
|
368
|
+
Menus: services.menus(),
|
|
369
|
+
IsMultiLingual: services.isMultiLanguage(),
|
|
370
|
+
LanguageCode: services.defaultLanguage()
|
|
371
|
+
}));
|
|
372
|
+
}
|
|
373
|
+
registerResourcesFunctions(funcMap, services) {
|
|
374
|
+
funcMap.set('resources', () => ({
|
|
375
|
+
Get: async (filename) => await services.Get(filename),
|
|
376
|
+
Minify: async (resource) => await services.Minify(resource),
|
|
377
|
+
Fingerprint: async (resource) => await services.Fingerprint(resource),
|
|
378
|
+
ExecuteAsTemplate: async (targetPath, data, resource) => await services.ExecuteAsTemplate(targetPath, data, resource)
|
|
379
|
+
}));
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Register Hugo template functions using HugoInfoService
|
|
383
|
+
* Equivalent to Go's registerHugo()
|
|
384
|
+
*/
|
|
385
|
+
registerHugoFunctions(funcMap, services) {
|
|
386
|
+
funcMap.set('hugo', () => ({
|
|
387
|
+
Version: services.version(),
|
|
388
|
+
Environment: services.environment(),
|
|
389
|
+
Generator: services.generator()
|
|
390
|
+
}));
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Register language template functions using LanguageService
|
|
394
|
+
* Equivalent to Go's registerLang()
|
|
395
|
+
*/
|
|
396
|
+
registerLanguageFunctions(funcMap, services) {
|
|
397
|
+
funcMap.set('i18n', (key) => {
|
|
398
|
+
// Placeholder for i18n functionality
|
|
399
|
+
return key;
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Register string manipulation functions
|
|
404
|
+
* Equivalent to Go's registerStrings()
|
|
405
|
+
*/
|
|
406
|
+
registerStringFunctions(funcMap) {
|
|
407
|
+
// Humanize converts ID-style strings to human readable format
|
|
408
|
+
funcMap.set('humanize', (str) => {
|
|
409
|
+
if (!str)
|
|
410
|
+
return '';
|
|
411
|
+
// Convert from camelCase or PascalCase
|
|
412
|
+
str = str.replace(/([a-z])([A-Z])/g, '$1 $2');
|
|
413
|
+
// Convert from snake_case or kebab-case
|
|
414
|
+
str = str.replace(/[_-]+/g, ' ');
|
|
415
|
+
// Remove file extensions
|
|
416
|
+
str = str.replace(/\.[^/.]+$/, '');
|
|
417
|
+
// Capitalize first letter, rest lowercase
|
|
418
|
+
str = str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
419
|
+
// Trim spaces
|
|
420
|
+
return str.trim();
|
|
421
|
+
});
|
|
422
|
+
funcMap.set('upper', (str) => str.toUpperCase());
|
|
423
|
+
funcMap.set('lower', (str) => str.toLowerCase());
|
|
424
|
+
funcMap.set('title', (str) => str.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()));
|
|
425
|
+
funcMap.set('trim', (str) => str.trim());
|
|
426
|
+
funcMap.set('replace', (str, old, newStr) => str.replace(new RegExp(old, 'g'), newStr));
|
|
427
|
+
// Split function - ensure first parameter is the string to split
|
|
428
|
+
funcMap.set('split', (str, sep) => {
|
|
429
|
+
// Handle null and undefined cases first
|
|
430
|
+
if (str === null || str === undefined) {
|
|
431
|
+
log.warn('split function: first argument is null or undefined');
|
|
432
|
+
return [];
|
|
433
|
+
}
|
|
434
|
+
if (typeof str !== 'string') {
|
|
435
|
+
log.warn('split function: first argument must be a string, got:', typeof str, 'value:', str);
|
|
436
|
+
// If it's an array, try to join it or return as is
|
|
437
|
+
if (Array.isArray(str)) {
|
|
438
|
+
return str;
|
|
439
|
+
}
|
|
440
|
+
// Try to convert to string
|
|
441
|
+
const stringValue = String(str);
|
|
442
|
+
return stringValue.split(sep);
|
|
443
|
+
}
|
|
444
|
+
return str.split(sep);
|
|
445
|
+
});
|
|
446
|
+
// Join function
|
|
447
|
+
funcMap.set('delimit', (arr, sep) => {
|
|
448
|
+
if (Array.isArray(arr)) {
|
|
449
|
+
return arr.join(sep);
|
|
450
|
+
}
|
|
451
|
+
return String(arr);
|
|
452
|
+
});
|
|
453
|
+
// Contains function
|
|
454
|
+
funcMap.set('in', (arr, item) => {
|
|
455
|
+
if (Array.isArray(arr)) {
|
|
456
|
+
return arr.includes(item);
|
|
457
|
+
}
|
|
458
|
+
return false;
|
|
459
|
+
});
|
|
460
|
+
// HasPrefix function
|
|
461
|
+
funcMap.set('hasPrefix', (str, prefix) => str.startsWith(prefix));
|
|
462
|
+
// HasSuffix function
|
|
463
|
+
funcMap.set('hasSuffix', (str, suffix) => str.endsWith(suffix));
|
|
464
|
+
// Strings namespace - following Go's strings namespace pattern
|
|
465
|
+
funcMap.set('strings', () => ({
|
|
466
|
+
// Basic string operations
|
|
467
|
+
ToLower: (s) => String(s).toLowerCase(),
|
|
468
|
+
ToUpper: (s) => String(s).toUpperCase(),
|
|
469
|
+
Title: (s) => String(s).replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()),
|
|
470
|
+
// Trimming functions
|
|
471
|
+
Trim: (s, cutset) => String(s).split('').filter(c => !cutset.includes(c)).join(''),
|
|
472
|
+
TrimSpace: (s) => String(s).trim(),
|
|
473
|
+
TrimLeft: (cutset, s) => {
|
|
474
|
+
const str = String(s);
|
|
475
|
+
let i = 0;
|
|
476
|
+
while (i < str.length && cutset.includes(str[i])) {
|
|
477
|
+
i++;
|
|
478
|
+
}
|
|
479
|
+
return str.slice(i);
|
|
480
|
+
},
|
|
481
|
+
TrimRight: (cutset, s) => {
|
|
482
|
+
const str = String(s);
|
|
483
|
+
let i = str.length - 1;
|
|
484
|
+
while (i >= 0 && cutset.includes(str[i])) {
|
|
485
|
+
i--;
|
|
486
|
+
}
|
|
487
|
+
return str.slice(0, i + 1);
|
|
488
|
+
},
|
|
489
|
+
TrimPrefix: (prefix, s) => {
|
|
490
|
+
const str = String(s);
|
|
491
|
+
return str.startsWith(prefix) ? str.slice(prefix.length) : str;
|
|
492
|
+
},
|
|
493
|
+
TrimSuffix: (suffix, s) => {
|
|
494
|
+
const str = String(s);
|
|
495
|
+
return str.endsWith(suffix) ? str.slice(0, -suffix.length) : str;
|
|
496
|
+
},
|
|
497
|
+
// Testing functions
|
|
498
|
+
Contains: (s, substr) => String(s).includes(substr),
|
|
499
|
+
ContainsAny: (s, chars) => {
|
|
500
|
+
const str = String(s);
|
|
501
|
+
return chars.split('').some(char => str.includes(char));
|
|
502
|
+
},
|
|
503
|
+
HasPrefix: (s, prefix) => String(s).startsWith(prefix),
|
|
504
|
+
HasSuffix: (s, suffix) => String(s).endsWith(suffix),
|
|
505
|
+
// Replacement functions
|
|
506
|
+
Replace: (s, old, newStr, limit) => {
|
|
507
|
+
const str = String(s);
|
|
508
|
+
if (limit === undefined) {
|
|
509
|
+
return str.replace(new RegExp(old.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), newStr);
|
|
510
|
+
}
|
|
511
|
+
let count = 0;
|
|
512
|
+
return str.replace(new RegExp(old.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), (match) => {
|
|
513
|
+
if (count < limit) {
|
|
514
|
+
count++;
|
|
515
|
+
return newStr;
|
|
516
|
+
}
|
|
517
|
+
return match;
|
|
518
|
+
});
|
|
519
|
+
},
|
|
520
|
+
// Splitting and slicing
|
|
521
|
+
Split: (s, delimiter) => String(s).split(delimiter),
|
|
522
|
+
SliceString: (s, start, end) => {
|
|
523
|
+
const str = String(s);
|
|
524
|
+
return end !== undefined ? str.slice(start, end) : str.slice(start);
|
|
525
|
+
},
|
|
526
|
+
Substr: (s, start, length) => {
|
|
527
|
+
const str = String(s);
|
|
528
|
+
if (start < 0)
|
|
529
|
+
start = str.length + start;
|
|
530
|
+
if (start < 0)
|
|
531
|
+
start = 0;
|
|
532
|
+
if (start >= str.length)
|
|
533
|
+
return '';
|
|
534
|
+
if (length === undefined)
|
|
535
|
+
return str.slice(start);
|
|
536
|
+
if (length <= 0)
|
|
537
|
+
return '';
|
|
538
|
+
return str.slice(start, start + length);
|
|
539
|
+
},
|
|
540
|
+
// Utility functions
|
|
541
|
+
Count: (substr, s) => {
|
|
542
|
+
const str = String(s);
|
|
543
|
+
if (!substr)
|
|
544
|
+
return str.length + 1;
|
|
545
|
+
return (str.match(new RegExp(substr.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')) || []).length;
|
|
546
|
+
},
|
|
547
|
+
CountWords: (s) => {
|
|
548
|
+
const str = String(s).trim();
|
|
549
|
+
return str ? str.split(/\s+/).length : 0;
|
|
550
|
+
},
|
|
551
|
+
CountRunes: (s) => {
|
|
552
|
+
const str = String(s);
|
|
553
|
+
return str.replace(/\s/g, '').length;
|
|
554
|
+
},
|
|
555
|
+
RuneCount: (s) => String(s).length,
|
|
556
|
+
// Repeat function
|
|
557
|
+
Repeat: (n, s) => {
|
|
558
|
+
if (n < 0)
|
|
559
|
+
throw new Error('strings: negative Repeat count');
|
|
560
|
+
return String(s).repeat(n);
|
|
561
|
+
},
|
|
562
|
+
// First letter upper
|
|
563
|
+
FirstUpper: (s) => {
|
|
564
|
+
const str = String(s);
|
|
565
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
566
|
+
}
|
|
567
|
+
}));
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Register math functions
|
|
571
|
+
* Equivalent to Go's registerMath()
|
|
572
|
+
*/
|
|
573
|
+
registerMathFunctions(funcMap) {
|
|
574
|
+
// Basic arithmetic functions
|
|
575
|
+
funcMap.set('add', (a, b) => a + b);
|
|
576
|
+
funcMap.set('sub', (a, b) => a - b);
|
|
577
|
+
funcMap.set('mul', (a, b) => a * b);
|
|
578
|
+
funcMap.set('div', (a, b) => b !== 0 ? a / b : 0);
|
|
579
|
+
funcMap.set('mod', (a, b) => b !== 0 ? a % b : 0);
|
|
580
|
+
// Math namespace functions - following Go's math package
|
|
581
|
+
funcMap.set('math', () => ({
|
|
582
|
+
// Abs returns the absolute value of n
|
|
583
|
+
Abs: (n) => {
|
|
584
|
+
const num = Number(n);
|
|
585
|
+
if (isNaN(num)) {
|
|
586
|
+
throw new Error('the math.Abs function requires a numeric argument');
|
|
587
|
+
}
|
|
588
|
+
return Math.abs(num);
|
|
589
|
+
},
|
|
590
|
+
// Add adds the multivalued addends
|
|
591
|
+
Add: (...inputs) => {
|
|
592
|
+
if (inputs.length < 2) {
|
|
593
|
+
throw new Error('must provide at least two numbers');
|
|
594
|
+
}
|
|
595
|
+
return inputs.reduce((sum, val) => {
|
|
596
|
+
const num = Number(val);
|
|
597
|
+
if (isNaN(num)) {
|
|
598
|
+
throw new Error('Add operator can\'t be used with non-numeric values');
|
|
599
|
+
}
|
|
600
|
+
return sum + num;
|
|
601
|
+
}, 0);
|
|
602
|
+
},
|
|
603
|
+
// Ceil returns the least integer value greater than or equal to n
|
|
604
|
+
Ceil: (n) => {
|
|
605
|
+
const num = Number(n);
|
|
606
|
+
if (isNaN(num)) {
|
|
607
|
+
throw new Error('Ceil operator can\'t be used with non-numeric value');
|
|
608
|
+
}
|
|
609
|
+
return Math.ceil(num);
|
|
610
|
+
},
|
|
611
|
+
// Div divides n1 by n2
|
|
612
|
+
Div: (...inputs) => {
|
|
613
|
+
if (inputs.length < 2) {
|
|
614
|
+
throw new Error('must provide at least two numbers');
|
|
615
|
+
}
|
|
616
|
+
const result = inputs.reduce((quotient, val, index) => {
|
|
617
|
+
const num = Number(val);
|
|
618
|
+
if (isNaN(num)) {
|
|
619
|
+
throw new Error('Div operator can\'t be used with non-numeric values');
|
|
620
|
+
}
|
|
621
|
+
if (index === 0)
|
|
622
|
+
return num;
|
|
623
|
+
if (num === 0) {
|
|
624
|
+
throw new Error('division by zero');
|
|
625
|
+
}
|
|
626
|
+
return quotient / num;
|
|
627
|
+
});
|
|
628
|
+
return result;
|
|
629
|
+
},
|
|
630
|
+
// Floor returns the greatest integer value less than or equal to n
|
|
631
|
+
Floor: (n) => {
|
|
632
|
+
const num = Number(n);
|
|
633
|
+
if (isNaN(num)) {
|
|
634
|
+
throw new Error('Floor operator can\'t be used with non-numeric value');
|
|
635
|
+
}
|
|
636
|
+
return Math.floor(num);
|
|
637
|
+
},
|
|
638
|
+
// Log returns the natural logarithm of n
|
|
639
|
+
Log: (n) => {
|
|
640
|
+
const num = Number(n);
|
|
641
|
+
if (isNaN(num)) {
|
|
642
|
+
throw new Error('Log operator can\'t be used with non-numeric value');
|
|
643
|
+
}
|
|
644
|
+
return Math.log(num);
|
|
645
|
+
},
|
|
646
|
+
// Max returns the greater of all numbers in inputs
|
|
647
|
+
Max: (...inputs) => {
|
|
648
|
+
if (inputs.length === 0) {
|
|
649
|
+
throw new Error('must provide at least one number');
|
|
650
|
+
}
|
|
651
|
+
const numbers = inputs.flat().map(val => {
|
|
652
|
+
const num = Number(val);
|
|
653
|
+
if (isNaN(num)) {
|
|
654
|
+
throw new Error('Max operator can\'t be used with non-numeric values');
|
|
655
|
+
}
|
|
656
|
+
return num;
|
|
657
|
+
});
|
|
658
|
+
return Math.max(...numbers);
|
|
659
|
+
},
|
|
660
|
+
// Min returns the smaller of all numbers in inputs
|
|
661
|
+
Min: (...inputs) => {
|
|
662
|
+
if (inputs.length === 0) {
|
|
663
|
+
throw new Error('must provide at least one number');
|
|
664
|
+
}
|
|
665
|
+
const numbers = inputs.flat().map(val => {
|
|
666
|
+
const num = Number(val);
|
|
667
|
+
if (isNaN(num)) {
|
|
668
|
+
throw new Error('Min operator can\'t be used with non-numeric values');
|
|
669
|
+
}
|
|
670
|
+
return num;
|
|
671
|
+
});
|
|
672
|
+
return Math.min(...numbers);
|
|
673
|
+
},
|
|
674
|
+
// Mod returns n1 % n2
|
|
675
|
+
Mod: (n1, n2) => {
|
|
676
|
+
const a = Number(n1);
|
|
677
|
+
const b = Number(n2);
|
|
678
|
+
if (isNaN(a) || isNaN(b)) {
|
|
679
|
+
throw new Error('modulo operator can\'t be used with non-numeric value');
|
|
680
|
+
}
|
|
681
|
+
if (b === 0) {
|
|
682
|
+
throw new Error('the number can\'t be divided by zero at modulo operation');
|
|
683
|
+
}
|
|
684
|
+
return a % b;
|
|
685
|
+
},
|
|
686
|
+
// ModBool returns the boolean of n1 % n2. If n1 % n2 == 0, return true
|
|
687
|
+
ModBool: (n1, n2) => {
|
|
688
|
+
const a = Number(n1);
|
|
689
|
+
const b = Number(n2);
|
|
690
|
+
if (isNaN(a) || isNaN(b)) {
|
|
691
|
+
throw new Error('modulo operator can\'t be used with non-numeric value');
|
|
692
|
+
}
|
|
693
|
+
if (b === 0) {
|
|
694
|
+
throw new Error('the number can\'t be divided by zero at modulo operation');
|
|
695
|
+
}
|
|
696
|
+
return (a % b) === 0;
|
|
697
|
+
},
|
|
698
|
+
// Mul multiplies the multivalued numbers
|
|
699
|
+
Mul: (...inputs) => {
|
|
700
|
+
if (inputs.length < 2) {
|
|
701
|
+
throw new Error('must provide at least two numbers');
|
|
702
|
+
}
|
|
703
|
+
return inputs.reduce((product, val) => {
|
|
704
|
+
const num = Number(val);
|
|
705
|
+
if (isNaN(num)) {
|
|
706
|
+
throw new Error('Mul operator can\'t be used with non-numeric values');
|
|
707
|
+
}
|
|
708
|
+
return product * num;
|
|
709
|
+
}, 1);
|
|
710
|
+
},
|
|
711
|
+
// Pow returns n1 raised to the power of n2
|
|
712
|
+
Pow: (n1, n2) => {
|
|
713
|
+
const a = Number(n1);
|
|
714
|
+
const b = Number(n2);
|
|
715
|
+
if (isNaN(a) || isNaN(b)) {
|
|
716
|
+
throw new Error('Pow operator can\'t be used with non-numeric value');
|
|
717
|
+
}
|
|
718
|
+
return Math.pow(a, b);
|
|
719
|
+
},
|
|
720
|
+
// Rand returns a pseudo-random number in [0.0,1.0)
|
|
721
|
+
Rand: () => Math.random(),
|
|
722
|
+
// Round returns the integer nearest to n
|
|
723
|
+
Round: (n) => {
|
|
724
|
+
const num = Number(n);
|
|
725
|
+
if (isNaN(num)) {
|
|
726
|
+
throw new Error('Round operator can\'t be used with non-numeric value');
|
|
727
|
+
}
|
|
728
|
+
return Math.round(num);
|
|
729
|
+
},
|
|
730
|
+
// Sqrt returns the square root of n
|
|
731
|
+
Sqrt: (n) => {
|
|
732
|
+
const num = Number(n);
|
|
733
|
+
if (isNaN(num)) {
|
|
734
|
+
throw new Error('Sqrt operator can\'t be used with non-numeric value');
|
|
735
|
+
}
|
|
736
|
+
return Math.sqrt(num);
|
|
737
|
+
},
|
|
738
|
+
// Sub subtracts multivalued numbers
|
|
739
|
+
Sub: (...inputs) => {
|
|
740
|
+
if (inputs.length < 2) {
|
|
741
|
+
throw new Error('must provide at least two numbers');
|
|
742
|
+
}
|
|
743
|
+
return inputs.reduce((difference, val, index) => {
|
|
744
|
+
const num = Number(val);
|
|
745
|
+
if (isNaN(num)) {
|
|
746
|
+
throw new Error('Sub operator can\'t be used with non-numeric values');
|
|
747
|
+
}
|
|
748
|
+
if (index === 0)
|
|
749
|
+
return num;
|
|
750
|
+
return difference - num;
|
|
751
|
+
});
|
|
752
|
+
},
|
|
753
|
+
// Sum returns the sum of all numbers in inputs
|
|
754
|
+
Sum: (...inputs) => {
|
|
755
|
+
if (inputs.length === 0) {
|
|
756
|
+
throw new Error('must provide at least one number');
|
|
757
|
+
}
|
|
758
|
+
const numbers = inputs.flat().map(val => {
|
|
759
|
+
const num = Number(val);
|
|
760
|
+
if (isNaN(num)) {
|
|
761
|
+
throw new Error('Sum operator can\'t be used with non-numeric values');
|
|
762
|
+
}
|
|
763
|
+
return num;
|
|
764
|
+
});
|
|
765
|
+
return numbers.reduce((sum, num) => sum + num, 0);
|
|
766
|
+
},
|
|
767
|
+
// Product returns the product of all numbers in inputs
|
|
768
|
+
Product: (...inputs) => {
|
|
769
|
+
if (inputs.length === 0) {
|
|
770
|
+
throw new Error('must provide at least one number');
|
|
771
|
+
}
|
|
772
|
+
const numbers = inputs.flat().map(val => {
|
|
773
|
+
const num = Number(val);
|
|
774
|
+
if (isNaN(num)) {
|
|
775
|
+
throw new Error('Product operator can\'t be used with non-numeric values');
|
|
776
|
+
}
|
|
777
|
+
return num;
|
|
778
|
+
});
|
|
779
|
+
return numbers.reduce((product, num) => product * num, 1);
|
|
780
|
+
}
|
|
781
|
+
}));
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Register time/date functions
|
|
785
|
+
* Equivalent to Go's registerTime()
|
|
786
|
+
*/
|
|
787
|
+
registerTimeFunctions(funcMap) {
|
|
788
|
+
// Time namespace functions - following Go's time package
|
|
789
|
+
funcMap.set('time', () => ({
|
|
790
|
+
// AsTime converts a value to a time.Time
|
|
791
|
+
AsTime: (v) => {
|
|
792
|
+
if (!v)
|
|
793
|
+
return null;
|
|
794
|
+
// If it's already a Date object
|
|
795
|
+
if (v instanceof Date)
|
|
796
|
+
return v;
|
|
797
|
+
// If it's a string, try to parse it
|
|
798
|
+
if (typeof v === 'string') {
|
|
799
|
+
const date = new Date(v);
|
|
800
|
+
return isNaN(date.getTime()) ? null : date;
|
|
801
|
+
}
|
|
802
|
+
// If it's a number (unix timestamp)
|
|
803
|
+
if (typeof v === 'number') {
|
|
804
|
+
// Check if it's in seconds (Unix timestamp) or milliseconds
|
|
805
|
+
const date = new Date(v < 1e10 ? v * 1000 : v);
|
|
806
|
+
return isNaN(date.getTime()) ? null : date;
|
|
807
|
+
}
|
|
808
|
+
return null;
|
|
809
|
+
},
|
|
810
|
+
// Format formats a time.Time
|
|
811
|
+
Format: (layout, value) => {
|
|
812
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
813
|
+
if (isNaN(date.getTime())) {
|
|
814
|
+
return '';
|
|
815
|
+
}
|
|
816
|
+
// Go time format parsing - based on reference time: Mon Jan 2 15:04:05 MST 2006
|
|
817
|
+
const year = date.getFullYear();
|
|
818
|
+
const month = date.getMonth() + 1; // JavaScript months are 0-based
|
|
819
|
+
const day = date.getDate();
|
|
820
|
+
const hour = date.getHours();
|
|
821
|
+
const minute = date.getMinutes();
|
|
822
|
+
const second = date.getSeconds();
|
|
823
|
+
const weekday = date.toLocaleString('en-US', { weekday: 'short' });
|
|
824
|
+
const monthName = date.toLocaleString('en-US', { month: 'short' });
|
|
825
|
+
// Go format patterns in order of precedence (longer patterns first)
|
|
826
|
+
const patterns = [
|
|
827
|
+
{ pattern: '2006', value: year.toString() },
|
|
828
|
+
{ pattern: '06', value: year.toString().slice(-2) },
|
|
829
|
+
{ pattern: 'January', value: date.toLocaleString('en-US', { month: 'long' }) },
|
|
830
|
+
{ pattern: 'Jan', value: monthName },
|
|
831
|
+
{ pattern: '01', value: month.toString().padStart(2, '0') },
|
|
832
|
+
{ pattern: '1', value: month.toString() },
|
|
833
|
+
{ pattern: 'Monday', value: date.toLocaleString('en-US', { weekday: 'long' }) },
|
|
834
|
+
{ pattern: 'Mon', value: weekday },
|
|
835
|
+
{ pattern: '02', value: day.toString().padStart(2, '0') },
|
|
836
|
+
{ pattern: '2', value: day.toString() },
|
|
837
|
+
{ pattern: '15', value: hour.toString().padStart(2, '0') },
|
|
838
|
+
{ pattern: '3', value: ((hour + 11) % 12 + 1).toString() },
|
|
839
|
+
{ pattern: '04', value: minute.toString().padStart(2, '0') },
|
|
840
|
+
{ pattern: '4', value: minute.toString() },
|
|
841
|
+
{ pattern: '05', value: second.toString().padStart(2, '0') },
|
|
842
|
+
{ pattern: '5', value: second.toString() },
|
|
843
|
+
{ pattern: 'PM', value: hour >= 12 ? 'PM' : 'AM' },
|
|
844
|
+
{ pattern: 'pm', value: hour >= 12 ? 'pm' : 'am' },
|
|
845
|
+
{ pattern: 'MST', value: date.toLocaleString('en-US', { timeZoneName: 'short' }) },
|
|
846
|
+
];
|
|
847
|
+
let result = layout;
|
|
848
|
+
for (const { pattern, value } of patterns) {
|
|
849
|
+
result = result.replace(new RegExp(pattern, 'g'), value);
|
|
850
|
+
}
|
|
851
|
+
return result;
|
|
852
|
+
},
|
|
853
|
+
// Now returns the current time
|
|
854
|
+
Now: () => new Date(),
|
|
855
|
+
// Parse parses a formatted string and returns the time value it represents
|
|
856
|
+
Parse: (layout, value) => {
|
|
857
|
+
try {
|
|
858
|
+
const date = new Date(value);
|
|
859
|
+
return isNaN(date.getTime()) ? null : date;
|
|
860
|
+
}
|
|
861
|
+
catch {
|
|
862
|
+
return null;
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
// Unix returns the Unix time in seconds
|
|
866
|
+
Unix: (value) => {
|
|
867
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
868
|
+
return Math.floor(date.getTime() / 1000);
|
|
869
|
+
},
|
|
870
|
+
// UnixNano returns the Unix time in nanoseconds
|
|
871
|
+
UnixNano: (value) => {
|
|
872
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
873
|
+
return date.getTime() * 1e6; // Convert milliseconds to nanoseconds
|
|
874
|
+
}
|
|
875
|
+
}));
|
|
876
|
+
// Now function that returns an object with Format method (Go-style)
|
|
877
|
+
funcMap.set('now', () => {
|
|
878
|
+
const date = new Date();
|
|
879
|
+
return {
|
|
880
|
+
Format: (layout) => {
|
|
881
|
+
// Go time format parsing - based on reference time: Mon Jan 2 15:04:05 MST 2006
|
|
882
|
+
// This represents Unix time 1136239445
|
|
883
|
+
const year = date.getFullYear();
|
|
884
|
+
const month = date.getMonth() + 1; // JavaScript months are 0-based
|
|
885
|
+
const day = date.getDate();
|
|
886
|
+
const hour = date.getHours();
|
|
887
|
+
const minute = date.getMinutes();
|
|
888
|
+
const second = date.getSeconds();
|
|
889
|
+
// Go format patterns in order of precedence (longer patterns first to avoid conflicts)
|
|
890
|
+
const patterns = [
|
|
891
|
+
// Year patterns
|
|
892
|
+
{ pattern: '2006', value: year.toString() }, // 4-digit year
|
|
893
|
+
{ pattern: '06', value: year.toString().slice(-2) }, // 2-digit year
|
|
894
|
+
// Month patterns
|
|
895
|
+
{ pattern: '01', value: month.toString().padStart(2, '0') }, // 2-digit month
|
|
896
|
+
{ pattern: '1', value: month.toString() }, // 1-digit month
|
|
897
|
+
// Day patterns
|
|
898
|
+
{ pattern: '02', value: day.toString().padStart(2, '0') }, // 2-digit day
|
|
899
|
+
{ pattern: '2', value: day.toString() }, // 1-digit day
|
|
900
|
+
// Hour patterns (24-hour)
|
|
901
|
+
{ pattern: '15', value: hour.toString().padStart(2, '0') }, // 2-digit hour (24h)
|
|
902
|
+
// Hour patterns (12-hour)
|
|
903
|
+
{ pattern: '3', value: ((hour % 12) || 12).toString() }, // 1-digit hour (12h)
|
|
904
|
+
// Minute patterns
|
|
905
|
+
{ pattern: '04', value: minute.toString().padStart(2, '0') }, // 2-digit minute
|
|
906
|
+
{ pattern: '4', value: minute.toString() }, // 1-digit minute
|
|
907
|
+
// Second patterns
|
|
908
|
+
{ pattern: '05', value: second.toString().padStart(2, '0') }, // 2-digit second
|
|
909
|
+
{ pattern: '5', value: second.toString() }, // 1-digit second
|
|
910
|
+
];
|
|
911
|
+
let result = layout;
|
|
912
|
+
// Apply patterns in order, using word boundaries to avoid partial matches
|
|
913
|
+
for (const { pattern, value } of patterns) {
|
|
914
|
+
// Use a more precise regex that considers word boundaries and context
|
|
915
|
+
const regex = new RegExp(`\\b${pattern}\\b`, 'g');
|
|
916
|
+
result = result.replace(regex, value);
|
|
917
|
+
}
|
|
918
|
+
// Handle some special cases that might not have word boundaries
|
|
919
|
+
// For patterns that might be standalone or part of other formatting
|
|
920
|
+
if (layout === '2006') {
|
|
921
|
+
return year.toString(); // Pure year format
|
|
922
|
+
}
|
|
923
|
+
if (layout === '06') {
|
|
924
|
+
return year.toString().slice(-2); // Pure 2-digit year format
|
|
925
|
+
}
|
|
926
|
+
if (layout === '01') {
|
|
927
|
+
return month.toString().padStart(2, '0'); // Pure month format
|
|
928
|
+
}
|
|
929
|
+
if (layout === '02') {
|
|
930
|
+
return day.toString().padStart(2, '0'); // Pure day format
|
|
931
|
+
}
|
|
932
|
+
if (layout === '15') {
|
|
933
|
+
return hour.toString().padStart(2, '0'); // Pure hour format
|
|
934
|
+
}
|
|
935
|
+
if (layout === '04') {
|
|
936
|
+
return minute.toString().padStart(2, '0'); // Pure minute format
|
|
937
|
+
}
|
|
938
|
+
if (layout === '05') {
|
|
939
|
+
return second.toString().padStart(2, '0'); // Pure second format
|
|
940
|
+
}
|
|
941
|
+
return result;
|
|
942
|
+
},
|
|
943
|
+
// Also provide direct access to the Date object
|
|
944
|
+
getTime: () => date.getTime(),
|
|
945
|
+
toString: () => date.toString(),
|
|
946
|
+
toISOString: () => date.toISOString()
|
|
947
|
+
};
|
|
948
|
+
});
|
|
949
|
+
funcMap.set('dateFormat', (format, date) => {
|
|
950
|
+
// Simple date formatting - can be enhanced with proper library
|
|
951
|
+
return date.toLocaleDateString();
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
/**
|
|
955
|
+
* Register collection functions
|
|
956
|
+
* Equivalent to Go's registerCollections()
|
|
957
|
+
*/
|
|
958
|
+
registerCollectionFunctions(funcMap) {
|
|
959
|
+
funcMap.set('len', (obj) => {
|
|
960
|
+
if (Array.isArray(obj))
|
|
961
|
+
return obj.length;
|
|
962
|
+
if (typeof obj === 'string')
|
|
963
|
+
return obj.length;
|
|
964
|
+
if (obj && typeof obj === 'object')
|
|
965
|
+
return Object.keys(obj).length;
|
|
966
|
+
return 0;
|
|
967
|
+
});
|
|
968
|
+
funcMap.set('first', (arr, n) => {
|
|
969
|
+
if (!Array.isArray(arr))
|
|
970
|
+
return [];
|
|
971
|
+
return n ? arr.slice(0, n) : arr.slice(0, 1);
|
|
972
|
+
});
|
|
973
|
+
funcMap.set('last', (arr, n) => {
|
|
974
|
+
if (!Array.isArray(arr))
|
|
975
|
+
return [];
|
|
976
|
+
return n ? arr.slice(-n) : arr.slice(-1);
|
|
977
|
+
});
|
|
978
|
+
// Merge function for combining objects/maps
|
|
979
|
+
funcMap.set('merge', (...args) => {
|
|
980
|
+
const result = {};
|
|
981
|
+
for (const arg of args) {
|
|
982
|
+
if (arg && typeof arg === 'object' && !Array.isArray(arg)) {
|
|
983
|
+
Object.assign(result, arg);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
return result;
|
|
987
|
+
});
|
|
988
|
+
// Index function to get item at index - supports nested indexing like Go's implementation
|
|
989
|
+
// Usage: {{ index array 0 }} or {{ index object "key" }} or {{ index nested "key1" "key2" 0 }}
|
|
990
|
+
funcMap.set('index', (item, ...indices) => {
|
|
991
|
+
try {
|
|
992
|
+
return this.doIndex(item, indices);
|
|
993
|
+
}
|
|
994
|
+
catch (error) {
|
|
995
|
+
log.error(`Index of type ${typeof item} with args [${indices.join(', ')}] failed:`, error);
|
|
996
|
+
return null;
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
// Reverse function
|
|
1000
|
+
funcMap.set('reverse', (arr) => {
|
|
1001
|
+
if (Array.isArray(arr)) {
|
|
1002
|
+
return [...arr].reverse();
|
|
1003
|
+
}
|
|
1004
|
+
return arr;
|
|
1005
|
+
});
|
|
1006
|
+
// Append function
|
|
1007
|
+
funcMap.set('append', (...args) => {
|
|
1008
|
+
if (args.length < 2) {
|
|
1009
|
+
return args[0] || [];
|
|
1010
|
+
}
|
|
1011
|
+
const result = Array.isArray(args[0]) ? [...args[0]] : [args[0]];
|
|
1012
|
+
// For each remaining argument, spread it if it's an array, otherwise add as single element
|
|
1013
|
+
for (let i = 1; i < args.length; i++) {
|
|
1014
|
+
if (Array.isArray(args[i])) {
|
|
1015
|
+
result.push(...args[i]);
|
|
1016
|
+
}
|
|
1017
|
+
else {
|
|
1018
|
+
result.push(args[i]);
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
return result;
|
|
1022
|
+
});
|
|
1023
|
+
// Prepend function
|
|
1024
|
+
funcMap.set('prepend', (arr, ...items) => {
|
|
1025
|
+
if (Array.isArray(arr)) {
|
|
1026
|
+
return [...items, ...arr];
|
|
1027
|
+
}
|
|
1028
|
+
return [...items, arr];
|
|
1029
|
+
});
|
|
1030
|
+
// Seq creates a sequence of integers from args. It's named and used as GNU's seq.
|
|
1031
|
+
// Examples:
|
|
1032
|
+
// 3 => 1, 2, 3
|
|
1033
|
+
// 1 2 4 => 1, 3
|
|
1034
|
+
// -3 => -1, -2, -3
|
|
1035
|
+
// 1 4 => 1, 2, 3, 4
|
|
1036
|
+
// 1 -2 => 1, 0, -1, -2
|
|
1037
|
+
funcMap.set('seq', (...args) => {
|
|
1038
|
+
if (args.length < 1 || args.length > 3) {
|
|
1039
|
+
throw new Error('invalid number of arguments to Seq');
|
|
1040
|
+
}
|
|
1041
|
+
// Convert all arguments to integers
|
|
1042
|
+
const intArgs = args.map(arg => {
|
|
1043
|
+
const num = Number(arg);
|
|
1044
|
+
if (isNaN(num)) {
|
|
1045
|
+
throw new Error('invalid arguments to Seq');
|
|
1046
|
+
}
|
|
1047
|
+
return Math.floor(num);
|
|
1048
|
+
});
|
|
1049
|
+
let inc = 1;
|
|
1050
|
+
let last;
|
|
1051
|
+
let first = intArgs[0];
|
|
1052
|
+
if (intArgs.length === 1) {
|
|
1053
|
+
last = first;
|
|
1054
|
+
if (last === 0) {
|
|
1055
|
+
return [];
|
|
1056
|
+
}
|
|
1057
|
+
else if (last > 0) {
|
|
1058
|
+
first = 1;
|
|
1059
|
+
}
|
|
1060
|
+
else {
|
|
1061
|
+
first = -1;
|
|
1062
|
+
inc = -1;
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
else if (intArgs.length === 2) {
|
|
1066
|
+
last = intArgs[1];
|
|
1067
|
+
if (last < first) {
|
|
1068
|
+
inc = -1;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
else {
|
|
1072
|
+
inc = intArgs[1];
|
|
1073
|
+
last = intArgs[2];
|
|
1074
|
+
if (inc === 0) {
|
|
1075
|
+
throw new Error("'increment' must not be 0");
|
|
1076
|
+
}
|
|
1077
|
+
if (first < last && inc < 0) {
|
|
1078
|
+
throw new Error("'increment' must be > 0");
|
|
1079
|
+
}
|
|
1080
|
+
if (first > last && inc > 0) {
|
|
1081
|
+
throw new Error("'increment' must be < 0");
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
// Sanity check
|
|
1085
|
+
if (last < -100000) {
|
|
1086
|
+
throw new Error('size of result exceeds limit');
|
|
1087
|
+
}
|
|
1088
|
+
const size = Math.floor((last - first) / inc) + 1;
|
|
1089
|
+
// Sanity check
|
|
1090
|
+
if (size <= 0 || size > 2000) {
|
|
1091
|
+
throw new Error('size of result exceeds limit');
|
|
1092
|
+
}
|
|
1093
|
+
const seq = new Array(size);
|
|
1094
|
+
let val = first;
|
|
1095
|
+
for (let i = 0; i < size; i++) {
|
|
1096
|
+
seq[i] = val;
|
|
1097
|
+
val += inc;
|
|
1098
|
+
if ((inc < 0 && val < last) || (inc > 0 && val > last)) {
|
|
1099
|
+
break;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
return seq;
|
|
1103
|
+
});
|
|
1104
|
+
// Sort returns a sorted copy of the list l
|
|
1105
|
+
// Equivalent to Go's Sort function in collections namespace
|
|
1106
|
+
// Usage: sort list [sortByField] [direction]
|
|
1107
|
+
// Examples:
|
|
1108
|
+
// {{ sort .Pages }} - sort by default comparison
|
|
1109
|
+
// {{ sort .Pages "Title" }} - sort by Title field ascending
|
|
1110
|
+
// {{ sort .Pages "Date" "desc" }} - sort by Date field descending
|
|
1111
|
+
funcMap.set('sort', (list, ...args) => {
|
|
1112
|
+
if (list === null || list === undefined) {
|
|
1113
|
+
throw new Error('sequence must be provided');
|
|
1114
|
+
}
|
|
1115
|
+
let arr;
|
|
1116
|
+
// Handle different input types
|
|
1117
|
+
if (Array.isArray(list)) {
|
|
1118
|
+
arr = [...list]; // Create a copy to avoid mutating original
|
|
1119
|
+
}
|
|
1120
|
+
else if (typeof list === 'object' && list !== null) {
|
|
1121
|
+
// Handle objects/maps - convert to array of values
|
|
1122
|
+
arr = Object.values(list);
|
|
1123
|
+
}
|
|
1124
|
+
else {
|
|
1125
|
+
throw new Error(`can't sort ${typeof list}`);
|
|
1126
|
+
}
|
|
1127
|
+
if (arr.length === 0) {
|
|
1128
|
+
return arr;
|
|
1129
|
+
}
|
|
1130
|
+
// Parse arguments
|
|
1131
|
+
let sortByField = '';
|
|
1132
|
+
let sortAsc = true;
|
|
1133
|
+
for (let i = 0; i < args.length; i++) {
|
|
1134
|
+
const arg = args[i];
|
|
1135
|
+
if (i === 0) {
|
|
1136
|
+
// First argument is the field to sort by
|
|
1137
|
+
if (typeof arg === 'string') {
|
|
1138
|
+
sortByField = arg;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
else if (i === 1) {
|
|
1142
|
+
// Second argument is the sort direction
|
|
1143
|
+
if (typeof arg === 'string' && arg.toLowerCase() === 'desc') {
|
|
1144
|
+
sortAsc = false;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
// Helper function to get nested property value
|
|
1149
|
+
const getNestedValue = (obj, path) => {
|
|
1150
|
+
if (!path || path === 'value') {
|
|
1151
|
+
return obj;
|
|
1152
|
+
}
|
|
1153
|
+
const keys = path.split('.');
|
|
1154
|
+
let current = obj;
|
|
1155
|
+
for (const key of keys) {
|
|
1156
|
+
if (current === null || current === undefined) {
|
|
1157
|
+
return undefined;
|
|
1158
|
+
}
|
|
1159
|
+
// Handle both object properties and method calls
|
|
1160
|
+
if (typeof current === 'object') {
|
|
1161
|
+
current = current[key];
|
|
1162
|
+
}
|
|
1163
|
+
else {
|
|
1164
|
+
return undefined;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return current;
|
|
1168
|
+
};
|
|
1169
|
+
// Comparison function
|
|
1170
|
+
const compare = (a, b) => {
|
|
1171
|
+
let aVal = sortByField ? getNestedValue(a, sortByField) : a;
|
|
1172
|
+
let bVal = sortByField ? getNestedValue(b, sortByField) : b;
|
|
1173
|
+
// Handle undefined/null values
|
|
1174
|
+
if (aVal === undefined || aVal === null) {
|
|
1175
|
+
if (bVal === undefined || bVal === null) {
|
|
1176
|
+
return 0;
|
|
1177
|
+
}
|
|
1178
|
+
return sortAsc ? -1 : 1;
|
|
1179
|
+
}
|
|
1180
|
+
if (bVal === undefined || bVal === null) {
|
|
1181
|
+
return sortAsc ? 1 : -1;
|
|
1182
|
+
}
|
|
1183
|
+
// Convert to comparable values
|
|
1184
|
+
if (typeof aVal === 'string' && typeof bVal === 'string') {
|
|
1185
|
+
const result = aVal.localeCompare(bVal);
|
|
1186
|
+
return sortAsc ? result : -result;
|
|
1187
|
+
}
|
|
1188
|
+
if (typeof aVal === 'number' && typeof bVal === 'number') {
|
|
1189
|
+
const result = aVal - bVal;
|
|
1190
|
+
return sortAsc ? result : -result;
|
|
1191
|
+
}
|
|
1192
|
+
// For mixed types, convert to strings and compare
|
|
1193
|
+
const aStr = String(aVal);
|
|
1194
|
+
const bStr = String(bVal);
|
|
1195
|
+
const result = aStr.localeCompare(bStr);
|
|
1196
|
+
return sortAsc ? result : -result;
|
|
1197
|
+
};
|
|
1198
|
+
// Sort the array
|
|
1199
|
+
return arr.sort(compare);
|
|
1200
|
+
});
|
|
1201
|
+
// where function - filters a collection based on conditions
|
|
1202
|
+
// Usage: {{ where .Pages "Section" "blog" }}
|
|
1203
|
+
// Usage: {{ where .Pages "Params.tags" "intersect" (slice "hugo" "go") }}
|
|
1204
|
+
funcMap.set('where', (() => {
|
|
1205
|
+
return (collection, key, ...args) => {
|
|
1206
|
+
if (!collection) {
|
|
1207
|
+
return [];
|
|
1208
|
+
}
|
|
1209
|
+
// Parse arguments to get value and operator
|
|
1210
|
+
let matchValue;
|
|
1211
|
+
let operator = '=='; // default operator
|
|
1212
|
+
if (args.length === 1) {
|
|
1213
|
+
matchValue = args[0];
|
|
1214
|
+
}
|
|
1215
|
+
else if (args.length === 2) {
|
|
1216
|
+
operator = args[0];
|
|
1217
|
+
matchValue = args[1];
|
|
1218
|
+
}
|
|
1219
|
+
else {
|
|
1220
|
+
throw new Error('where function requires 2-4 arguments');
|
|
1221
|
+
}
|
|
1222
|
+
const result = [];
|
|
1223
|
+
// Handle different collection types
|
|
1224
|
+
if (Array.isArray(collection)) {
|
|
1225
|
+
for (let i = 0; i < collection.length; i++) {
|
|
1226
|
+
const item = collection[i];
|
|
1227
|
+
const itemValue = this.getNestedValue(item, key);
|
|
1228
|
+
if (this.checkCondition(itemValue, matchValue, operator)) {
|
|
1229
|
+
result.push(item);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
else if (typeof collection === 'object') {
|
|
1234
|
+
// Handle object/map
|
|
1235
|
+
for (const [mapKey, mapValue] of Object.entries(collection)) {
|
|
1236
|
+
if (Array.isArray(mapValue)) {
|
|
1237
|
+
const filtered = mapValue.filter(item => {
|
|
1238
|
+
const itemValue = this.getNestedValue(item, key);
|
|
1239
|
+
return this.checkCondition(itemValue, matchValue, operator);
|
|
1240
|
+
});
|
|
1241
|
+
if (filtered.length > 0) {
|
|
1242
|
+
result.push({ [mapKey]: filtered });
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return result;
|
|
1248
|
+
};
|
|
1249
|
+
})());
|
|
1250
|
+
// intersect function - finds intersection of two arrays
|
|
1251
|
+
funcMap.set('intersect', (set1, set2) => {
|
|
1252
|
+
if (!Array.isArray(set1) || !Array.isArray(set2)) {
|
|
1253
|
+
return [];
|
|
1254
|
+
}
|
|
1255
|
+
return set1.filter(item => set2.includes(item));
|
|
1256
|
+
});
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* Core indexing implementation following Go's doIndex logic
|
|
1260
|
+
* Supports nested indexing of arrays, objects, and maps
|
|
1261
|
+
*/
|
|
1262
|
+
doIndex(item, indices) {
|
|
1263
|
+
// Handle null/undefined item
|
|
1264
|
+
if (item === null || item === undefined) {
|
|
1265
|
+
return null;
|
|
1266
|
+
}
|
|
1267
|
+
// If no indices provided, return the item itself
|
|
1268
|
+
if (indices.length === 0) {
|
|
1269
|
+
return item;
|
|
1270
|
+
}
|
|
1271
|
+
let currentValue = item;
|
|
1272
|
+
// Process each index in sequence (supports chained indexing like x[1][2][3])
|
|
1273
|
+
for (const index of indices) {
|
|
1274
|
+
// Handle null/undefined current value in chain
|
|
1275
|
+
if (currentValue === null || currentValue === undefined) {
|
|
1276
|
+
return null;
|
|
1277
|
+
}
|
|
1278
|
+
// Determine how to index based on the current value type
|
|
1279
|
+
if (Array.isArray(currentValue)) {
|
|
1280
|
+
// Handle array/slice indexing
|
|
1281
|
+
currentValue = this.indexArray(currentValue, index);
|
|
1282
|
+
}
|
|
1283
|
+
else if (typeof currentValue === 'string') {
|
|
1284
|
+
// Handle string indexing (strings are indexable like arrays)
|
|
1285
|
+
currentValue = this.indexString(currentValue, index);
|
|
1286
|
+
}
|
|
1287
|
+
else if (typeof currentValue === 'object') {
|
|
1288
|
+
// Handle object/map indexing (including TaxonomyList type)
|
|
1289
|
+
currentValue = this.indexObject(currentValue, index);
|
|
1290
|
+
}
|
|
1291
|
+
else {
|
|
1292
|
+
// Cannot index this type
|
|
1293
|
+
throw new Error(`can't index item of type ${typeof currentValue}`);
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
return currentValue;
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* Index into an array or slice
|
|
1300
|
+
*/
|
|
1301
|
+
indexArray(arr, index) {
|
|
1302
|
+
// Convert index to integer
|
|
1303
|
+
const i = this.toInteger(index);
|
|
1304
|
+
if (i === null) {
|
|
1305
|
+
throw new Error(`cannot index slice/array with type ${typeof index}`);
|
|
1306
|
+
}
|
|
1307
|
+
// Check bounds - Go version returns null for out of bounds instead of error
|
|
1308
|
+
if (i < 0 || i >= arr.length) {
|
|
1309
|
+
return null;
|
|
1310
|
+
}
|
|
1311
|
+
return arr[i];
|
|
1312
|
+
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Index into a string (treating it like a character array)
|
|
1315
|
+
*/
|
|
1316
|
+
indexString(str, index) {
|
|
1317
|
+
// Convert index to integer
|
|
1318
|
+
const i = this.toInteger(index);
|
|
1319
|
+
if (i === null) {
|
|
1320
|
+
throw new Error(`cannot index string with type ${typeof index}`);
|
|
1321
|
+
}
|
|
1322
|
+
// Check bounds
|
|
1323
|
+
if (i < 0 || i >= str.length) {
|
|
1324
|
+
return null;
|
|
1325
|
+
}
|
|
1326
|
+
return str.charAt(i);
|
|
1327
|
+
}
|
|
1328
|
+
/**
|
|
1329
|
+
* Index into an object/map (including TaxonomyList)
|
|
1330
|
+
*/
|
|
1331
|
+
indexObject(obj, key) {
|
|
1332
|
+
// Convert key to string for object property access
|
|
1333
|
+
const keyStr = String(key);
|
|
1334
|
+
// Check if property exists
|
|
1335
|
+
if (obj.hasOwnProperty(keyStr)) {
|
|
1336
|
+
return obj[keyStr];
|
|
1337
|
+
}
|
|
1338
|
+
// Try case-insensitive lookup (following Hugo's behavior)
|
|
1339
|
+
const keys = Object.keys(obj);
|
|
1340
|
+
const matchingKey = keys.find(k => k.toLowerCase() === keyStr.toLowerCase());
|
|
1341
|
+
if (matchingKey) {
|
|
1342
|
+
return obj[matchingKey];
|
|
1343
|
+
}
|
|
1344
|
+
// Map
|
|
1345
|
+
if (obj instanceof Map) {
|
|
1346
|
+
if (obj.has(keyStr)) {
|
|
1347
|
+
return obj.get(keyStr);
|
|
1348
|
+
}
|
|
1349
|
+
// case-insensitive 查找
|
|
1350
|
+
for (const k of obj.keys()) {
|
|
1351
|
+
if (String(k).toLowerCase() === keyStr.toLowerCase()) {
|
|
1352
|
+
return obj.get(k);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
// Property not found - return undefined/null like Go's zero value
|
|
1357
|
+
return null;
|
|
1358
|
+
}
|
|
1359
|
+
/**
|
|
1360
|
+
* Convert value to integer, similar to Go's index conversion
|
|
1361
|
+
*/
|
|
1362
|
+
toInteger(value) {
|
|
1363
|
+
if (typeof value === 'number') {
|
|
1364
|
+
if (Number.isInteger(value)) {
|
|
1365
|
+
return value;
|
|
1366
|
+
}
|
|
1367
|
+
// Convert float to int (truncate)
|
|
1368
|
+
return Math.floor(value);
|
|
1369
|
+
}
|
|
1370
|
+
if (typeof value === 'string') {
|
|
1371
|
+
const parsed = parseInt(value, 10);
|
|
1372
|
+
if (!isNaN(parsed)) {
|
|
1373
|
+
return parsed;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1376
|
+
// Cannot convert to integer
|
|
1377
|
+
return null;
|
|
1378
|
+
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Check condition between two values using the specified operator
|
|
1381
|
+
* Following golang's checkCondition logic
|
|
1382
|
+
*/
|
|
1383
|
+
checkCondition(value, matchValue, operator) {
|
|
1384
|
+
// Normalize operator
|
|
1385
|
+
const op = operator.toLowerCase().trim();
|
|
1386
|
+
// Handle null/undefined cases
|
|
1387
|
+
if (value == null && matchValue == null) {
|
|
1388
|
+
return ['==', '=', 'eq', ''].includes(op);
|
|
1389
|
+
}
|
|
1390
|
+
if (value == null || matchValue == null) {
|
|
1391
|
+
return ['!=', '<>', 'ne'].includes(op);
|
|
1392
|
+
}
|
|
1393
|
+
// Handle array membership (in operator)
|
|
1394
|
+
if (op === 'in') {
|
|
1395
|
+
if (Array.isArray(matchValue)) {
|
|
1396
|
+
return matchValue.includes(value);
|
|
1397
|
+
}
|
|
1398
|
+
if (typeof matchValue === 'string' && typeof value === 'string') {
|
|
1399
|
+
return matchValue.includes(value);
|
|
1400
|
+
}
|
|
1401
|
+
return false;
|
|
1402
|
+
}
|
|
1403
|
+
// Handle intersect operator for arrays
|
|
1404
|
+
if (op === 'intersect') {
|
|
1405
|
+
if (Array.isArray(value) && Array.isArray(matchValue)) {
|
|
1406
|
+
return value.some(item => matchValue.includes(item));
|
|
1407
|
+
}
|
|
1408
|
+
return false;
|
|
1409
|
+
}
|
|
1410
|
+
// Type conversion for comparison
|
|
1411
|
+
const [normalizedValue, normalizedMatch] = this.normalizeForComparison(value, matchValue);
|
|
1412
|
+
switch (op) {
|
|
1413
|
+
case '':
|
|
1414
|
+
case '=':
|
|
1415
|
+
case '==':
|
|
1416
|
+
case 'eq':
|
|
1417
|
+
return normalizedValue === normalizedMatch;
|
|
1418
|
+
case '!=':
|
|
1419
|
+
case '<>':
|
|
1420
|
+
case 'ne':
|
|
1421
|
+
return normalizedValue !== normalizedMatch;
|
|
1422
|
+
case '<':
|
|
1423
|
+
case 'lt':
|
|
1424
|
+
return normalizedValue < normalizedMatch;
|
|
1425
|
+
case '<=':
|
|
1426
|
+
case 'le':
|
|
1427
|
+
return normalizedValue <= normalizedMatch;
|
|
1428
|
+
case '>':
|
|
1429
|
+
case 'gt':
|
|
1430
|
+
return normalizedValue > normalizedMatch;
|
|
1431
|
+
case '>=':
|
|
1432
|
+
case 'ge':
|
|
1433
|
+
return normalizedValue >= normalizedMatch;
|
|
1434
|
+
default:
|
|
1435
|
+
return false;
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Normalize values for comparison
|
|
1440
|
+
*/
|
|
1441
|
+
normalizeForComparison(value, matchValue) {
|
|
1442
|
+
// If both are numbers, compare as numbers
|
|
1443
|
+
if (typeof value === 'number' && typeof matchValue === 'number') {
|
|
1444
|
+
return [value, matchValue];
|
|
1445
|
+
}
|
|
1446
|
+
// If one is number and other is string number, convert both to numbers
|
|
1447
|
+
if (typeof value === 'number' && typeof matchValue === 'string') {
|
|
1448
|
+
const num = parseFloat(matchValue);
|
|
1449
|
+
if (!isNaN(num)) {
|
|
1450
|
+
return [value, num];
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
if (typeof value === 'string' && typeof matchValue === 'number') {
|
|
1454
|
+
const num = parseFloat(value);
|
|
1455
|
+
if (!isNaN(num)) {
|
|
1456
|
+
return [num, matchValue];
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
// If both are strings, compare as strings
|
|
1460
|
+
if (typeof value === 'string' && typeof matchValue === 'string') {
|
|
1461
|
+
return [value, matchValue];
|
|
1462
|
+
}
|
|
1463
|
+
// If both are booleans, compare as booleans
|
|
1464
|
+
if (typeof value === 'boolean' && typeof matchValue === 'boolean') {
|
|
1465
|
+
return [value, matchValue];
|
|
1466
|
+
}
|
|
1467
|
+
// Default: convert both to strings for comparison
|
|
1468
|
+
return [String(value), String(matchValue)];
|
|
1469
|
+
}
|
|
1470
|
+
/**
|
|
1471
|
+
* Register safe functions
|
|
1472
|
+
* Equivalent to Go's registerSafe()
|
|
1473
|
+
*/
|
|
1474
|
+
registerSafeFunctions(funcMap) {
|
|
1475
|
+
// Return function - implements early return like Go's template.Return
|
|
1476
|
+
// Usage: {{ return VALUE }}
|
|
1477
|
+
funcMap.set('return', (...args) => {
|
|
1478
|
+
// If no arguments provided, return empty string
|
|
1479
|
+
if (args.length === 0) {
|
|
1480
|
+
return '';
|
|
1481
|
+
}
|
|
1482
|
+
// If single argument, return it directly
|
|
1483
|
+
if (args.length === 1) {
|
|
1484
|
+
return args[0];
|
|
1485
|
+
}
|
|
1486
|
+
// If multiple arguments, return them as an array
|
|
1487
|
+
return args;
|
|
1488
|
+
});
|
|
1489
|
+
// Cond function - implements conditional branching like Go's template.Cond
|
|
1490
|
+
// Usage: {{ cond CONDITION VALUE_IF_TRUE VALUE_IF_FALSE }}
|
|
1491
|
+
funcMap.set('cond', (...args) => {
|
|
1492
|
+
if (args.length < 2) {
|
|
1493
|
+
throw new Error('cond requires at least 2 arguments');
|
|
1494
|
+
}
|
|
1495
|
+
const condition = args[0];
|
|
1496
|
+
const trueValue = args[1];
|
|
1497
|
+
const falseValue = args.length > 2 ? args[2] : '';
|
|
1498
|
+
// Convert condition to boolean, following Go's truthiness rules
|
|
1499
|
+
let isTrue = false;
|
|
1500
|
+
if (condition === true || condition === 1) {
|
|
1501
|
+
isTrue = true;
|
|
1502
|
+
}
|
|
1503
|
+
else if (typeof condition === 'string') {
|
|
1504
|
+
isTrue = condition.length > 0 && condition !== "false" && condition !== "0";
|
|
1505
|
+
}
|
|
1506
|
+
else if (typeof condition === 'number') {
|
|
1507
|
+
isTrue = condition !== 0;
|
|
1508
|
+
}
|
|
1509
|
+
else if (Array.isArray(condition)) {
|
|
1510
|
+
isTrue = condition.length > 0;
|
|
1511
|
+
}
|
|
1512
|
+
else if (condition && typeof condition === 'object') {
|
|
1513
|
+
isTrue = Object.keys(condition).length > 0;
|
|
1514
|
+
}
|
|
1515
|
+
return isTrue ? trueValue : falseValue;
|
|
1516
|
+
});
|
|
1517
|
+
funcMap.set('safeHTML', (str) => str);
|
|
1518
|
+
funcMap.set('safeCSS', (str) => str);
|
|
1519
|
+
funcMap.set('safeJS', (str) => str);
|
|
1520
|
+
funcMap.set('safeURL', (str) => str);
|
|
1521
|
+
// Dict function for creating key-value maps
|
|
1522
|
+
funcMap.set('dict', (...args) => {
|
|
1523
|
+
if (args.length % 2 !== 0) {
|
|
1524
|
+
throw new Error('dict requires an even number of arguments');
|
|
1525
|
+
}
|
|
1526
|
+
const result = {};
|
|
1527
|
+
for (let i = 0; i < args.length; i += 2) {
|
|
1528
|
+
result[String(args[i])] = args[i + 1];
|
|
1529
|
+
}
|
|
1530
|
+
return result;
|
|
1531
|
+
});
|
|
1532
|
+
// Slice function for creating arrays
|
|
1533
|
+
funcMap.set('slice', (...args) => {
|
|
1534
|
+
return args;
|
|
1535
|
+
});
|
|
1536
|
+
// Printf function for string formatting
|
|
1537
|
+
funcMap.set('printf', (format, ...args) => {
|
|
1538
|
+
// Simple printf implementation
|
|
1539
|
+
let result = format;
|
|
1540
|
+
args.forEach((arg, index) => {
|
|
1541
|
+
result = result.replace(new RegExp(`%[sdf]`, 'g'), String(arg));
|
|
1542
|
+
});
|
|
1543
|
+
return result;
|
|
1544
|
+
});
|
|
1545
|
+
// Default function for providing default values
|
|
1546
|
+
// TypeScript equivalent of Go's default function
|
|
1547
|
+
funcMap.set('default', (defaultValue, value) => {
|
|
1548
|
+
// Return the value if it exists and is not empty/null/undefined, otherwise return default
|
|
1549
|
+
if (value !== null && value !== undefined && value !== '' && value !== 0 && value !== false) {
|
|
1550
|
+
return value;
|
|
1551
|
+
}
|
|
1552
|
+
return defaultValue;
|
|
1553
|
+
});
|
|
1554
|
+
// Jsonify function - encodes a given object to JSON
|
|
1555
|
+
// Usage: {{ jsonify . }}
|
|
1556
|
+
// Usage: {{ jsonify (dict "indent" " ") . }}
|
|
1557
|
+
funcMap.set('jsonify', (...args) => {
|
|
1558
|
+
if (args.length === 0) {
|
|
1559
|
+
return '';
|
|
1560
|
+
}
|
|
1561
|
+
let obj;
|
|
1562
|
+
let opts = {};
|
|
1563
|
+
if (args.length === 1) {
|
|
1564
|
+
obj = args[0];
|
|
1565
|
+
}
|
|
1566
|
+
else if (args.length === 2) {
|
|
1567
|
+
// First argument is options, second is the object to jsonify
|
|
1568
|
+
const options = args[0];
|
|
1569
|
+
obj = args[1];
|
|
1570
|
+
if (options && typeof options === 'object') {
|
|
1571
|
+
opts.prefix = options.prefix || '';
|
|
1572
|
+
opts.indent = options.indent || '';
|
|
1573
|
+
opts.noHTMLEscape = options.noHTMLEscape || false;
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
else {
|
|
1577
|
+
throw new Error('too many arguments to jsonify');
|
|
1578
|
+
}
|
|
1579
|
+
try {
|
|
1580
|
+
let jsonString;
|
|
1581
|
+
if (opts.indent) {
|
|
1582
|
+
// Pretty print with indentation
|
|
1583
|
+
jsonString = JSON.stringify(obj, null, opts.indent);
|
|
1584
|
+
// Add prefix to each line if specified
|
|
1585
|
+
if (opts.prefix) {
|
|
1586
|
+
jsonString = jsonString
|
|
1587
|
+
.split('\n')
|
|
1588
|
+
.map(line => opts.prefix + line)
|
|
1589
|
+
.join('\n');
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
else {
|
|
1593
|
+
// Compact JSON
|
|
1594
|
+
jsonString = JSON.stringify(obj);
|
|
1595
|
+
}
|
|
1596
|
+
// Handle HTML escaping (by default, JSON.stringify doesn't escape HTML)
|
|
1597
|
+
if (!opts.noHTMLEscape) {
|
|
1598
|
+
jsonString = jsonString
|
|
1599
|
+
.replace(/&/g, '\\u0026')
|
|
1600
|
+
.replace(/</g, '\\u003c')
|
|
1601
|
+
.replace(/>/g, '\\u003e');
|
|
1602
|
+
}
|
|
1603
|
+
return jsonString;
|
|
1604
|
+
}
|
|
1605
|
+
catch (error) {
|
|
1606
|
+
throw new Error(`failed to jsonify object: ${error.message}`);
|
|
1607
|
+
}
|
|
1608
|
+
});
|
|
1609
|
+
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Register format functions (fmt namespace)
|
|
1612
|
+
* Equivalent to Go's registerFmt()
|
|
1613
|
+
*/
|
|
1614
|
+
registerFmtFunctions(funcMap) {
|
|
1615
|
+
// Basic printf, print, println functions (for backward compatibility)
|
|
1616
|
+
funcMap.set('printf', (format, ...args) => {
|
|
1617
|
+
// Simple printf implementation - you can enhance this with a proper sprintf library
|
|
1618
|
+
let result = format;
|
|
1619
|
+
for (let i = 0; i < args.length; i++) {
|
|
1620
|
+
result = result.replace(/%[sd%]/, String(args[i]));
|
|
1621
|
+
}
|
|
1622
|
+
return result;
|
|
1623
|
+
});
|
|
1624
|
+
funcMap.set('print', (...args) => {
|
|
1625
|
+
return args.map(arg => String(arg)).join(' ');
|
|
1626
|
+
});
|
|
1627
|
+
funcMap.set('println', (...args) => {
|
|
1628
|
+
return args.map(arg => String(arg)).join(' ') + '\n';
|
|
1629
|
+
});
|
|
1630
|
+
// Standalone errorf and warnf functions for backward compatibility
|
|
1631
|
+
funcMap.set('errorf', (format, ...args) => {
|
|
1632
|
+
let message = format;
|
|
1633
|
+
for (let i = 0; i < args.length; i++) {
|
|
1634
|
+
message = message.replace(/%[sd%]/, String(args[i]));
|
|
1635
|
+
}
|
|
1636
|
+
log.error("Template Error:", message);
|
|
1637
|
+
return ''; // errorf returns empty string but logs the error
|
|
1638
|
+
});
|
|
1639
|
+
funcMap.set('warnf', (format, ...args) => {
|
|
1640
|
+
let message = format;
|
|
1641
|
+
for (let i = 0; i < args.length; i++) {
|
|
1642
|
+
message = message.replace(/%[sd%]/, String(args[i]));
|
|
1643
|
+
}
|
|
1644
|
+
log.warn("Template Warning:", message);
|
|
1645
|
+
return ''; // warnf returns empty string but logs the warning
|
|
1646
|
+
});
|
|
1647
|
+
// Fmt namespace functions - following Go's fmt package
|
|
1648
|
+
funcMap.set('fmt', () => ({
|
|
1649
|
+
// Print returns a string representation of args
|
|
1650
|
+
Print: (...args) => {
|
|
1651
|
+
return args.map(arg => String(arg)).join(' ');
|
|
1652
|
+
},
|
|
1653
|
+
// Printf returns string representation of args formatted with the layout in format
|
|
1654
|
+
Printf: (format, ...args) => {
|
|
1655
|
+
let result = format;
|
|
1656
|
+
for (let i = 0; i < args.length; i++) {
|
|
1657
|
+
result = result.replace(/%[sd%]/, String(args[i]));
|
|
1658
|
+
}
|
|
1659
|
+
return result;
|
|
1660
|
+
},
|
|
1661
|
+
// Println returns string representation of args ending with a newline
|
|
1662
|
+
Println: (...args) => {
|
|
1663
|
+
return args.map(arg => String(arg)).join(' ') + '\n';
|
|
1664
|
+
},
|
|
1665
|
+
// Errorf formats args according to a format specifier and logs an ERROR
|
|
1666
|
+
// It returns an empty string
|
|
1667
|
+
Errorf: (format, ...args) => {
|
|
1668
|
+
let message = format;
|
|
1669
|
+
for (let i = 0; i < args.length; i++) {
|
|
1670
|
+
message = message.replace(/%[sd%]/, String(args[i]));
|
|
1671
|
+
}
|
|
1672
|
+
log.error("Template Error:", message);
|
|
1673
|
+
return '';
|
|
1674
|
+
},
|
|
1675
|
+
// Erroridf formats args according to a format specifier and logs an ERROR with ID
|
|
1676
|
+
// It returns an empty string
|
|
1677
|
+
Erroridf: (id, format, ...args) => {
|
|
1678
|
+
let message = format;
|
|
1679
|
+
for (let i = 0; i < args.length; i++) {
|
|
1680
|
+
message = message.replace(/%[sd%]/, String(args[i]));
|
|
1681
|
+
}
|
|
1682
|
+
log.error("Template Error:", message);
|
|
1683
|
+
return '';
|
|
1684
|
+
},
|
|
1685
|
+
// Warnf formats args according to a format specifier and logs a WARNING
|
|
1686
|
+
// It returns an empty string
|
|
1687
|
+
Warnf: (format, ...args) => {
|
|
1688
|
+
let message = format;
|
|
1689
|
+
for (let i = 0; i < args.length; i++) {
|
|
1690
|
+
message = message.replace(/%[sd%]/, String(args[i]));
|
|
1691
|
+
}
|
|
1692
|
+
log.error("Template Warning:", message);
|
|
1693
|
+
return '';
|
|
1694
|
+
},
|
|
1695
|
+
// Warnidf formats args according to a format specifier and logs a WARNING with ID
|
|
1696
|
+
// It returns an empty string
|
|
1697
|
+
Warnidf: (id, format, ...args) => {
|
|
1698
|
+
let message = format;
|
|
1699
|
+
for (let i = 0; i < args.length; i++) {
|
|
1700
|
+
message = message.replace(/%[sd%]/, String(args[i]));
|
|
1701
|
+
}
|
|
1702
|
+
log.error("Template Warning:", message);
|
|
1703
|
+
return '';
|
|
1704
|
+
}
|
|
1705
|
+
}));
|
|
1706
|
+
}
|
|
1707
|
+
/**
|
|
1708
|
+
* Register reflect functions
|
|
1709
|
+
* Equivalent to Go's registerReflect()
|
|
1710
|
+
*/
|
|
1711
|
+
registerReflectFunctions(funcMap) {
|
|
1712
|
+
// Reflect namespace functions - following Go's reflect package
|
|
1713
|
+
funcMap.set('reflect', () => ({
|
|
1714
|
+
// IsMap reports whether v is a map/object
|
|
1715
|
+
// Following Go's implementation: only true maps, not structs/classes
|
|
1716
|
+
IsMap: (v) => {
|
|
1717
|
+
if (v === null || v === undefined) {
|
|
1718
|
+
return false;
|
|
1719
|
+
}
|
|
1720
|
+
// Must be an object
|
|
1721
|
+
if (typeof v !== 'object' || Array.isArray(v)) {
|
|
1722
|
+
return false;
|
|
1723
|
+
}
|
|
1724
|
+
// In TypeScript/JavaScript context, we consider something a "map" only if:
|
|
1725
|
+
// 1. It's a plain Object (constructor === Object)
|
|
1726
|
+
// 2. OR it's a Map instance
|
|
1727
|
+
// 3. OR it was explicitly created as a dict/map (has no prototype methods)
|
|
1728
|
+
// Check for Map instance
|
|
1729
|
+
if (v instanceof Map) {
|
|
1730
|
+
return true;
|
|
1731
|
+
}
|
|
1732
|
+
// Check for plain object (like golang's map)
|
|
1733
|
+
if (v.constructor === Object) {
|
|
1734
|
+
return true;
|
|
1735
|
+
}
|
|
1736
|
+
// Check if it looks like a dict created by template functions
|
|
1737
|
+
// (has no methods, only data properties)
|
|
1738
|
+
const proto = Object.getPrototypeOf(v);
|
|
1739
|
+
if (proto === Object.prototype || proto === null) {
|
|
1740
|
+
return true;
|
|
1741
|
+
}
|
|
1742
|
+
// Everything else (including class instances like Page) is not a map
|
|
1743
|
+
return false;
|
|
1744
|
+
},
|
|
1745
|
+
// IsSlice reports whether v is a slice/array
|
|
1746
|
+
IsSlice: (v) => {
|
|
1747
|
+
return Array.isArray(v);
|
|
1748
|
+
}
|
|
1749
|
+
}));
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
* Register path manipulation functions
|
|
1753
|
+
* Equivalent to Go's path package functions
|
|
1754
|
+
*/
|
|
1755
|
+
registerPathFunctions(funcMap) {
|
|
1756
|
+
// Path namespace functions - following Go's path package
|
|
1757
|
+
funcMap.set('path', () => ({
|
|
1758
|
+
// Base returns the last element of path
|
|
1759
|
+
Base: (path) => {
|
|
1760
|
+
if (!path)
|
|
1761
|
+
return '.';
|
|
1762
|
+
// Trim trailing slashes
|
|
1763
|
+
path = path.replace(/\/+$/, '');
|
|
1764
|
+
if (!path)
|
|
1765
|
+
return '/';
|
|
1766
|
+
// Get the last part after the last slash
|
|
1767
|
+
const parts = path.split('/');
|
|
1768
|
+
return parts[parts.length - 1] || '/';
|
|
1769
|
+
},
|
|
1770
|
+
// Clean returns the shortest path name equivalent to path
|
|
1771
|
+
Clean: (path) => {
|
|
1772
|
+
if (!path)
|
|
1773
|
+
return '.';
|
|
1774
|
+
// Convert backslashes to forward slashes
|
|
1775
|
+
path = path.replace(/\\/g, '/');
|
|
1776
|
+
// Handle absolute paths
|
|
1777
|
+
const isAbs = path.startsWith('/');
|
|
1778
|
+
// Split path into parts
|
|
1779
|
+
const parts = path.split('/').filter(p => p && p !== '.');
|
|
1780
|
+
// Handle .. parts
|
|
1781
|
+
const stack = [];
|
|
1782
|
+
for (const part of parts) {
|
|
1783
|
+
if (part === '..') {
|
|
1784
|
+
if (stack.length > 0 && stack[stack.length - 1] !== '..') {
|
|
1785
|
+
stack.pop();
|
|
1786
|
+
}
|
|
1787
|
+
else if (!isAbs) {
|
|
1788
|
+
stack.push('..');
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
else {
|
|
1792
|
+
stack.push(part);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
// Join parts back together
|
|
1796
|
+
path = stack.join('/');
|
|
1797
|
+
if (isAbs)
|
|
1798
|
+
path = '/' + path;
|
|
1799
|
+
return path || (isAbs ? '/' : '.');
|
|
1800
|
+
},
|
|
1801
|
+
// Dir returns all but the last element of path
|
|
1802
|
+
Dir: (path) => {
|
|
1803
|
+
if (!path)
|
|
1804
|
+
return '.';
|
|
1805
|
+
// Trim trailing slashes
|
|
1806
|
+
path = path.replace(/\/+$/, '');
|
|
1807
|
+
if (!path)
|
|
1808
|
+
return '/';
|
|
1809
|
+
// Get everything before the last slash
|
|
1810
|
+
const parts = path.split('/');
|
|
1811
|
+
parts.pop();
|
|
1812
|
+
return parts.join('/') || '.';
|
|
1813
|
+
},
|
|
1814
|
+
// Ext returns the file name extension
|
|
1815
|
+
Ext: (path) => {
|
|
1816
|
+
const base = path.split('/').pop() || '';
|
|
1817
|
+
const dot = base.lastIndexOf('.');
|
|
1818
|
+
if (dot === -1 || dot === 0)
|
|
1819
|
+
return '';
|
|
1820
|
+
return base.substring(dot);
|
|
1821
|
+
},
|
|
1822
|
+
// IsAbs reports whether the path is absolute
|
|
1823
|
+
IsAbs: (path) => {
|
|
1824
|
+
return path.startsWith('/');
|
|
1825
|
+
},
|
|
1826
|
+
// Join joins any number of path elements into a single path
|
|
1827
|
+
Join: (...elements) => {
|
|
1828
|
+
if (elements.length === 0)
|
|
1829
|
+
return '.';
|
|
1830
|
+
// Filter out empty elements and handle trailing slashes
|
|
1831
|
+
const parts = elements
|
|
1832
|
+
.filter(e => e)
|
|
1833
|
+
.map(e => e.replace(/^\/+|\/+$/g, ''));
|
|
1834
|
+
// Join parts with single slashes
|
|
1835
|
+
let path = parts.join('/');
|
|
1836
|
+
// Handle absolute paths
|
|
1837
|
+
if (elements[0] && elements[0].startsWith('/')) {
|
|
1838
|
+
path = '/' + path;
|
|
1839
|
+
}
|
|
1840
|
+
return path || '.';
|
|
1841
|
+
},
|
|
1842
|
+
// Split splits path immediately following the final slash
|
|
1843
|
+
Split: (path) => {
|
|
1844
|
+
if (!path)
|
|
1845
|
+
return ['.', ''];
|
|
1846
|
+
// Find the last slash
|
|
1847
|
+
const lastSlash = path.lastIndexOf('/');
|
|
1848
|
+
if (lastSlash === -1) {
|
|
1849
|
+
return ['', path];
|
|
1850
|
+
}
|
|
1851
|
+
return [
|
|
1852
|
+
path.substring(0, lastSlash),
|
|
1853
|
+
path.substring(lastSlash + 1)
|
|
1854
|
+
];
|
|
1855
|
+
}
|
|
1856
|
+
}));
|
|
1857
|
+
}
|
|
1858
|
+
/**
|
|
1859
|
+
* Get nested value from object using dot notation path
|
|
1860
|
+
* Following golang's path resolution logic
|
|
1861
|
+
*/
|
|
1862
|
+
getNestedValue(obj, path) {
|
|
1863
|
+
if (!obj || !path) {
|
|
1864
|
+
return undefined;
|
|
1865
|
+
}
|
|
1866
|
+
// Handle special case where path starts with a dot
|
|
1867
|
+
const cleanPath = path.replace(/^\\.+/, '');
|
|
1868
|
+
const parts = cleanPath.split('.');
|
|
1869
|
+
let current = obj;
|
|
1870
|
+
for (let i = 0; i < parts.length; i++) {
|
|
1871
|
+
const part = parts[i];
|
|
1872
|
+
if (current == null) {
|
|
1873
|
+
return undefined;
|
|
1874
|
+
}
|
|
1875
|
+
// Handle array/object access
|
|
1876
|
+
if (typeof current === 'object') {
|
|
1877
|
+
// First try exact match (case-sensitive)
|
|
1878
|
+
if (current.hasOwnProperty(part)) {
|
|
1879
|
+
current = current[part];
|
|
1880
|
+
continue;
|
|
1881
|
+
}
|
|
1882
|
+
// Then try case-insensitive property access (like Hugo)
|
|
1883
|
+
const keys = Object.keys(current);
|
|
1884
|
+
const matchingKey = keys.find(k => k.toLowerCase() === part.toLowerCase());
|
|
1885
|
+
if (matchingKey) {
|
|
1886
|
+
current = current[matchingKey];
|
|
1887
|
+
continue;
|
|
1888
|
+
}
|
|
1889
|
+
// Special case: Try method call for common Hugo properties
|
|
1890
|
+
// Kind -> kind(), Content -> content(), etc.
|
|
1891
|
+
const methodName = part.toLowerCase();
|
|
1892
|
+
if (typeof current[methodName] === 'function') {
|
|
1893
|
+
try {
|
|
1894
|
+
current = current[methodName]();
|
|
1895
|
+
continue;
|
|
1896
|
+
}
|
|
1897
|
+
catch (error) {
|
|
1898
|
+
return undefined;
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
return undefined;
|
|
1902
|
+
}
|
|
1903
|
+
else {
|
|
1904
|
+
return undefined;
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
return current;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
exports.DefaultTemplateRegistry = DefaultTemplateRegistry;
|
|
1911
|
+
/**
|
|
1912
|
+
* Create default template registry
|
|
1913
|
+
*/
|
|
1914
|
+
function newTemplateRegistry() {
|
|
1915
|
+
return new DefaultTemplateRegistry();
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1918
|
+
* Convenience function to create and register core functions only
|
|
1919
|
+
*/
|
|
1920
|
+
function createCoreFuncMap() {
|
|
1921
|
+
const funcMap = new Map();
|
|
1922
|
+
const registry = newTemplateRegistry();
|
|
1923
|
+
registry.registerCoreFunctions(funcMap);
|
|
1924
|
+
return funcMap;
|
|
1925
|
+
}
|
|
1926
|
+
/**
|
|
1927
|
+
* Convenience function to create and register all functions with services
|
|
1928
|
+
*/
|
|
1929
|
+
function createStandardFuncMap(services) {
|
|
1930
|
+
const funcMap = new Map();
|
|
1931
|
+
const registry = newTemplateRegistry();
|
|
1932
|
+
registry.registerAllFunctions(funcMap, services);
|
|
1933
|
+
return funcMap;
|
|
1934
|
+
}
|
|
1935
|
+
/**
|
|
1936
|
+
* Update all engine-dependent functions with the template engine instance
|
|
1937
|
+
* This should be called after the template engine is created
|
|
1938
|
+
*/
|
|
1939
|
+
function updateEngineDependentFunctions(engine) {
|
|
1940
|
+
for (const func of engineDependentFunctions) {
|
|
1941
|
+
try {
|
|
1942
|
+
func.updateEngine(engine);
|
|
1943
|
+
log.info(`✅ Updated function: ${func.getFunctionName()}`);
|
|
1944
|
+
}
|
|
1945
|
+
catch (error) {
|
|
1946
|
+
log.error(`❌ Failed to update function ${func.getFunctionName()}:`, error);
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
//# sourceMappingURL=registry.js.map
|