Comparing version 0.1.1 to 0.2.0
#!/usr/bin/env node | ||
import { getHTML, getComponentFromString, mergeComponentToDocument, getSubDirectory } from '../lib/index.js' | ||
import { render } from 'dom-serializer' | ||
import { getHTML, parseHTMLDocument, parseModule, createComponent, getSubDirectory } from '#lib' | ||
import { Command } from 'commander' | ||
import { resolve, join } from 'node:path' | ||
import { join } from 'node:path' | ||
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs' | ||
/** @import { CoraliteComponent } from '#types' */ | ||
/** | ||
* @import { CoraliteModule } from '#types' | ||
*/ | ||
@@ -22,3 +25,3 @@ const pkg = JSON.parse(readFileSync(`./package.json`, 'utf-8')) | ||
program.parse() | ||
program.parse(process.argv) | ||
program.on('error', (err) => { | ||
@@ -43,8 +46,10 @@ console.error(err) | ||
/** @type {Object.<string, CoraliteComponent>} */ | ||
/** @type {Object.<string, CoraliteModule>} */ | ||
const components = {} | ||
// create components | ||
for (let i = 0; i < htmlComponents.length; i++) { | ||
const html = htmlComponents[i] | ||
const component = getComponentFromString(html.content) | ||
const component = parseModule(html.content) | ||
components[component.id] = component | ||
@@ -55,8 +60,26 @@ } | ||
const html = htmlPages[i] | ||
const content = await mergeComponentToDocument(html, components, { | ||
pages: resolve(pagesPath), | ||
components: resolve(componentsPath) | ||
const document = parseHTMLDocument(html, { | ||
pages: pagesPath, | ||
components: componentsPath | ||
}) | ||
for (let i = 0; i < document.customElements.length; i++) { | ||
const customElement = document.customElements[i] | ||
const component = await createComponent({ | ||
id: customElement.name, | ||
values: customElement.attribs, | ||
customElementSlots: document.customElementSlots, | ||
components, | ||
document | ||
}) | ||
// replace custom element with component | ||
customElement.parent.children.splice(customElement.parentChildIndex, 1, ...component.children) | ||
component.parent = customElement.parent | ||
} | ||
// render document | ||
// @ts-ignore | ||
const content = render(document.root) | ||
if (!dryRun) { | ||
@@ -63,0 +86,0 @@ // get pages sub directory |
@@ -5,5 +5,5 @@ { | ||
"module": "NodeNext", | ||
"target": "ES2020", | ||
"target": "ES2022", | ||
"moduleResolution": "nodenext", | ||
} | ||
} |
@@ -10,9 +10,17 @@ import { extname, join } from 'node:path' | ||
* Get HTML | ||
* @param {Object} options - html directory | ||
* @param {string} options.path - html directory | ||
* @param {boolean} [options.recursive] - If true, reads the contents of a directory recursively. In recursive mode, it will list all files, sub files and directories. Default: false. | ||
* @param {string[]} [options.exclude = []] - Exclude file by name | ||
* @returns {Promise<HTMLData[]>} | ||
* @param {Object} options - Options for searching HTML files | ||
* @param {string} options.path - Path to the directory containing HTML files | ||
* @param {boolean} [options.recursive=false] - Whether to search recursively in subdirectories | ||
* @param {string[]} [options.exclude=[]] - Files or directories to exclude from search | ||
* @returns {Promise<HTMLData[]>} Array of HTML file data including parent path, name, and content | ||
* | ||
* @example | ||
* // Example usage: | ||
* const htmlFiles = await getHTML({ | ||
* path: 'src', | ||
* recursive: true, | ||
* exclude: ['index.html', 'subdir/file2.html'] | ||
* }) | ||
*/ | ||
export default function getHTML ({ path, recursive, exclude = [] }) { | ||
export default function getHTML ({ path, recursive = false, exclude = [] }) { | ||
return new Promise((resolve, reject) => { | ||
@@ -19,0 +27,0 @@ const html = [] |
@@ -1,19 +0,8 @@ | ||
import getComponentFromString from './get-component-from-string.js' | ||
import getHTML from './get-html.js' | ||
import mergeComponentToDocument from './merge-component-to-document.js' | ||
import getTokensFromString from './get-tokens-from-string.js' | ||
import getScriptFromString from './get-script-from-string.js' | ||
import getMetadataFromDocument from './get-metadata-from-document.js' | ||
import getSubDirectory from './get-subdirectory.js' | ||
import evalComputedTokens from './eval-computed-tokens.js' | ||
export * from './parse.js' | ||
export * from './path-utils.js' | ||
export { | ||
evalComputedTokens, | ||
getSubDirectory, | ||
getMetadataFromDocument, | ||
getScriptFromString, | ||
getTokensFromString, | ||
getComponentFromString, | ||
mergeComponentToDocument, | ||
getHTML | ||
} |
{ | ||
"name": "coralite", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "HTML modules static site generator", | ||
@@ -23,12 +23,13 @@ "main": "./lib/coralite.js", | ||
"type": "git", | ||
"url": "git+https://github.com/tjdav/coralite.git" | ||
"url": "https://github.com/tjdav/coralite.git" | ||
}, | ||
"license": "MPL-2.0", | ||
"scripts": { | ||
"commitmsg": "commitlint -e", | ||
"format": "eslint --cache --fix .", | ||
"lint": "eslint --cache ." | ||
"lint": "eslint --cache .", | ||
"test-unit": "node --test test/lib/*", | ||
"semantic-release": "semantic-release" | ||
}, | ||
"bin": { | ||
"coralite": "./bin/coralite.js" | ||
}, | ||
"bin": "bin/coralite.js", | ||
"imports": { | ||
@@ -39,6 +40,8 @@ "#lib": "./lib/index.js", | ||
"exports": { | ||
"default": "./lib/component.js", | ||
"default": "./lib/coralite.js", | ||
"types": "./types/index.js" | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "^19.6.1", | ||
"@commitlint/config-conventional": "^19.6.0", | ||
"@stylistic/eslint-plugin-js": "^2.12.1", | ||
@@ -48,5 +51,11 @@ "@stylistic/eslint-plugin-plus": "^2.12.1", | ||
}, | ||
"engines": { | ||
"node": ">=18" | ||
}, | ||
"dependencies": { | ||
"commander": "^13.0.0" | ||
"acorn": "^8.14.0", | ||
"commander": "^13.0.0", | ||
"dom-serializer": "^2.0.0", | ||
"htmlparser2": "^10.0.0" | ||
} | ||
} |
# Coralite | ||
A simple static site generator based on `HTML modules` | ||
coralite is a static site generator library built around the emerging [HTML modules proposal](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md). | ||
## Installation | ||
Before using the Coralite CLI, ensure that it's installed on your system. You can install it globally using **npm**: | ||
```bash | ||
npm install -g coralite | ||
# or | ||
yarn global add coralite | ||
# or | ||
pnpm add -g coralite | ||
``` | ||
npm install coralite --save-dev | ||
``` | ||
You can also install coralite as a development dependency: | ||
```bash | ||
npm install --save-dev coralite | ||
# or | ||
yarn add -D coralite | ||
# or | ||
pnpm add -D coralite | ||
``` | ||
## Basic Syntax | ||
Coralite is executed using the following command: | ||
```bash | ||
coralite [options] | ||
``` | ||
Replace `[options]` with the desired flags and arguments. | ||
## Required Options | ||
To generate a website using Coralite, you must provide three essential options: | ||
- **-c or --components**: The path to your components directory containing reusable UI elements (e.g., `-c ./src/components`). | ||
- **-p or --pages**: The path to your pages directory where static HTML files reside (e.g., `-p ./src/pages`). | ||
- **--output or -o**: The output directory for the generated site (e.g., `--output ./dist`). | ||
Here's an example of how these options might look: | ||
```bash | ||
coralite --components ./src/components --pages ./src/pages --output ./dist | ||
``` | ||
## Optional Options | ||
### -d or --dry | ||
Run the CLI in dry-run mode to preview the actions that would be performed without actually generating the website. This is useful for debugging or when you want to check potential issues before committing changes: | ||
```bash | ||
coralite --components ./src/components --pages ./src/pages --output ./dist --dry | ||
``` |
/** | ||
* @callback coraliteComputedTokens | ||
* @param {Object} thisArgs | ||
* @returns {Promise<Object<string, string>>} | ||
* @typedef {Object} HTMLData | ||
* @property {string} parentPath - Path to the directory containing this file (e.g., '../my-component'). | ||
* @property {string} name - The file's name without extension (e.g., 'my-component'). | ||
* @property {string} content - The raw HTML string contents of the file. | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteToken | ||
* @property {string} name - Token name | ||
* @property {string} content - End position of token | ||
* Represents the paths to Coralite pages and components within a project. | ||
* @typedef {Object} CoralitePath | ||
* @property {string} pages - The path to the root pages directory | ||
* @property {string} components - The path to the root components directory | ||
*/ | ||
@@ -15,46 +17,95 @@ | ||
* @typedef {Object} CoraliteTokenOptions | ||
* @property {Object.<string, string>} [default] - Token defaults | ||
* @property {Object.<string, string[]>} [aliases] - Token aliases | ||
* @property {Object.<string, string>} [default] - Default token values for properties not explicitly set | ||
* @property {Object.<string, string[]>} [aliases] - Token aliases and their possible values | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteComponent | ||
* @property {string} id | ||
* @property {string} content | ||
* @property {CoraliteToken[]} tokens | ||
* @property {coraliteComputedTokens} computedTokens | ||
* @property {CoraliteCustomElement[]} customElements | ||
* @typedef {Object} CoraliteModule | ||
* @property {string} id - Unique module identifier | ||
* @property {CoraliteElement} template - Module's rendering template | ||
* @property {string|undefined} script - Module's JavaScript raw code | ||
* @property {CoraliteDocumentTokens} tokens - Tokens generated from the module's markup | ||
* @property {CoraliteElement[]} customElements - Custom elements defined in the module | ||
* @property {Object.<string, Object.<string,CoraliteModuleSlotElement>>} slotElements - Custom slot elements and their configurations | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteCustomElementResult | ||
* @property {string} content - Content body | ||
* @property {CoraliteCustomElement[]} customElements - Custom elements found in content body | ||
* @typedef {Object} CoraliteDocumentTokens | ||
* @property {CoraliteAttributeToken[]} attributes - Array of attribute tokens from the document | ||
* @property {CoraliteTextNodeToken[]} textNodes - Array of text node tokens from the document | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteCustomElementAttribute | ||
* @property {string} name - Attribute name | ||
* @property {string} value - Attribute value | ||
* @property {CoraliteToken[]} tokens - List of tokens used in attribute value | ||
* @typedef {Object} CoraliteToken | ||
* @property {string} name - Token identifier | ||
* @property {string} content - Token value or content | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteCustomElement | ||
* @property {string} id - Custom element ID | ||
* @property {CoraliteCustomElementAttribute[]} attributes - Custom element attributes | ||
* @property {string} content | ||
* @typedef {Object} CoraliteAttributeToken | ||
* @property {string} name - Attribute token identifier | ||
* @property {CoraliteElement} element - Corresponding HTML element for the attribute | ||
* @property {CoraliteToken[]} tokens - Array of associated tokens | ||
*/ | ||
/** | ||
* @typedef {Object} HTMLData | ||
* @property {string} parentPath - The path to the parent directory of the file. | ||
* @property {string} name - The file name. | ||
* @property {string} content - HTML string | ||
* @typedef {Object} CoraliteTextNodeToken | ||
* @property {'text'} type - Type of text node ('text') | ||
* @property {string} data - Text node raw data | ||
* @property {CoraliteElement} parent - Parent element of the text node | ||
*/ | ||
/** | ||
* @typedef {Object} CoralitePath | ||
* @property {string} pages | ||
* @property {string} components | ||
* @typedef {Object} CoraliteModuleSlotElement | ||
* @property {string} name - Slot element identifier | ||
* @property {CoraliteElement} element - Corresponding HTML element for the slot | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteElement | ||
* @property {'tag'} type - Element type | ||
* @property {string} name - Tag name | ||
* @property {Object.<string, string>} attribs - Element attributes | ||
* @property {(CoraliteElement | CoraliteTextNode)[]} children - Child nodes of the element | ||
* @property {CoraliteElement} parent - Parent element | ||
* @property {number} [parentChildIndex] - Position in parent's child list | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteTextNode | ||
* @property {'text'} type - Text node type | ||
* @property {string} data - Additional attributes for the text node | ||
* @property {CoraliteElement} parent - Parent element of the text node | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteSlotElement | ||
* @property {string} name - Slot's unique identifier | ||
* @property {CoraliteElement} customElement - Custom component for the slot | ||
* @property {CoraliteElement} element - Corresponding HTML element for the slot | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteDirective | ||
* @property {'directive'} type - Node type | ||
* @property {string} data - Raw HTML Doctype | ||
* @property {string} name - Doctype name | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteDocumentRoot | ||
* @property {'root'} type - Node type | ||
* @property {(CoraliteDirective | CoraliteElement | CoraliteTextNode)[]} children - Document list | ||
*/ | ||
/** | ||
* @typedef {Object} CoraliteDocument | ||
* @property {string} name - Document file name | ||
* @property {string} parentPath - Parent file path | ||
* @property {CoraliteDocumentRoot} root - Array of elements and text nodes in the document | ||
* @property {CoraliteElement[]} customElements - Custom elements defined in the document | ||
* @property {Object.<string, CoraliteSlotElement[]>} customElementSlots - Slots with their respective elements | ||
* @property {CoralitePath} path - Document's file path | ||
*/ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
61264
23
1247
59
4
5
+ Addedacorn@^8.14.0
+ Addeddom-serializer@^2.0.0
+ Addedhtmlparser2@^10.0.0
+ Addedacorn@8.14.0(transitive)
+ Addeddom-serializer@2.0.0(transitive)
+ Addeddomelementtype@2.3.0(transitive)
+ Addeddomhandler@5.0.3(transitive)
+ Addeddomutils@3.2.2(transitive)
+ Addedentities@4.5.06.0.0(transitive)
+ Addedhtmlparser2@10.0.0(transitive)