coralite 0.1.1 → 0.2.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/.github/docs/continue-commit-convention.md +11 -0
- package/.github/workflows/publish.yml +46 -0
- package/.idea/coralite.iml +12 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/jsLibraryMappings.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/README.md +52 -3
- package/bin/coralite.js +33 -10
- package/commitlint.config.js +3 -0
- package/jsconfig.json +1 -1
- package/lib/coralite.js +38 -0
- package/lib/get-html.js +14 -6
- package/lib/html-module.js +75 -0
- package/lib/index.js +3 -14
- package/lib/parse.js +820 -0
- package/lib/{get-subdirectory.js → path-utils.js} +1 -3
- package/lib/tags.js +145 -0
- package/package.json +17 -8
- package/release.config.js +11 -0
- package/types/index.js +83 -32
- package/lib/component.js +0 -185
- package/lib/eval-computed-tokens.js +0 -7
- package/lib/get-component-from-string.js +0 -39
- package/lib/get-custom-elements-from-string.js +0 -48
- package/lib/get-metadata-from-document.js +0 -41
- package/lib/get-script-from-string.js +0 -50
- package/lib/get-tokens-from-string.js +0 -26
- package/lib/merge-component-to-document.js +0 -54
- package/lib/replace-attribute-token-value.js +0 -23
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Based on the provided Git diff above, create a git commit message by strictly following these rules:
|
|
2
|
+
|
|
3
|
+
1. Use one of the predefined prefixes (feat, fix, perf, build, chore, ci, docs, style, refactor, test, types, wip) or a custom prefix for non-changelog related tasks.
|
|
4
|
+
2. The commit message must have a header, which includes a type and subject, separated by a colon.
|
|
5
|
+
3. Follow the imperative present tense for both the subject and body of the commit message:
|
|
6
|
+
- Use concise and descriptive subjects.
|
|
7
|
+
- Avoid including implementation details in the body unless necessary for understanding context.
|
|
8
|
+
4. Include an optional footer to provide information about breaking changes using the format "BREAKING CHANGE:" followed by additional details.
|
|
9
|
+
5. Limit line length to 72 characters and maintain consistent use of whitespace for better readability and uniformity.
|
|
10
|
+
6. If changes are about JSDoc, the prefix should be 'types'.
|
|
11
|
+
7. Use any suggestion below this to help with the context.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [created]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
steps:
|
|
11
|
+
- name: Checkout
|
|
12
|
+
uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- uses: pnpm/action-setup@v4
|
|
15
|
+
name: Install pnpm
|
|
16
|
+
with:
|
|
17
|
+
version: 9
|
|
18
|
+
run_install: false
|
|
19
|
+
|
|
20
|
+
- name: Install Node.js
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: 22
|
|
24
|
+
cache: "pnpm"
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: pnpm install
|
|
28
|
+
|
|
29
|
+
- name: Lint
|
|
30
|
+
run: pnpm run lint
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
publish-npm:
|
|
34
|
+
needs: build
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: actions/setup-node@v4
|
|
39
|
+
with:
|
|
40
|
+
node-version: 20
|
|
41
|
+
registry-url: https://registry.npmjs.org/
|
|
42
|
+
- run: npm ci
|
|
43
|
+
- run: npm publish
|
|
44
|
+
env:
|
|
45
|
+
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
|
46
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$">
|
|
5
|
+
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
6
|
+
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
7
|
+
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
+
</content>
|
|
9
|
+
<orderEntry type="inheritedJdk" />
|
|
10
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
|
+
</component>
|
|
12
|
+
</module>
|
package/.idea/vcs.xml
ADDED
package/README.md
CHANGED
|
@@ -1,9 +1,58 @@
|
|
|
1
1
|
# Coralite
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
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).
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
+
Before using the Coralite CLI, ensure that it's installed on your system. You can install it globally using **npm**:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g coralite
|
|
11
|
+
# or
|
|
12
|
+
yarn global add coralite
|
|
13
|
+
# or
|
|
14
|
+
pnpm add -g coralite
|
|
15
|
+
```
|
|
16
|
+
You can also install coralite as a development dependency:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install --save-dev coralite
|
|
20
|
+
# or
|
|
21
|
+
yarn add -D coralite
|
|
22
|
+
# or
|
|
23
|
+
pnpm add -D coralite
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Basic Syntax
|
|
27
|
+
|
|
28
|
+
Coralite is executed using the following command:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
coralite [options]
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Replace `[options]` with the desired flags and arguments.
|
|
35
|
+
|
|
36
|
+
## Required Options
|
|
37
|
+
|
|
38
|
+
To generate a website using Coralite, you must provide three essential options:
|
|
39
|
+
|
|
40
|
+
- **-c or --components**: The path to your components directory containing reusable UI elements (e.g., `-c ./src/components`).
|
|
41
|
+
- **-p or --pages**: The path to your pages directory where static HTML files reside (e.g., `-p ./src/pages`).
|
|
42
|
+
- **--output or -o**: The output directory for the generated site (e.g., `--output ./dist`).
|
|
43
|
+
|
|
44
|
+
Here's an example of how these options might look:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
coralite --components ./src/components --pages ./src/pages --output ./dist
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Optional Options
|
|
51
|
+
|
|
52
|
+
### -d or --dry
|
|
53
|
+
|
|
54
|
+
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:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
coralite --components ./src/components --pages ./src/pages --output ./dist --dry
|
|
7
58
|
```
|
|
8
|
-
npm install coralite --save-dev
|
|
9
|
-
```
|
package/bin/coralite.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { render } from 'dom-serializer'
|
|
4
|
+
import { getHTML, parseHTMLDocument, parseModule, createComponent, getSubDirectory } from '#lib'
|
|
4
5
|
import { Command } from 'commander'
|
|
5
|
-
import {
|
|
6
|
+
import { join } from 'node:path'
|
|
6
7
|
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs'
|
|
7
8
|
|
|
8
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* @import { CoraliteModule } from '#types'
|
|
11
|
+
*/
|
|
9
12
|
|
|
10
13
|
const pkg = JSON.parse(readFileSync(`./package.json`, 'utf-8'))
|
|
11
14
|
const program = new Command()
|
|
@@ -19,7 +22,7 @@ program
|
|
|
19
22
|
.requiredOption('-o, --output <path>', 'Output directory for the generated site')
|
|
20
23
|
.option('-d, --dry', 'Run in dry-run mode')
|
|
21
24
|
|
|
22
|
-
program.parse()
|
|
25
|
+
program.parse(process.argv)
|
|
23
26
|
program.on('error', (err) => {
|
|
24
27
|
console.error(err)
|
|
25
28
|
})
|
|
@@ -39,23 +42,43 @@ const htmlPages = await getHTML({
|
|
|
39
42
|
recursive: true
|
|
40
43
|
})
|
|
41
44
|
|
|
42
|
-
/** @type {Object.<string,
|
|
45
|
+
/** @type {Object.<string, CoraliteModule>} */
|
|
43
46
|
const components = {}
|
|
44
47
|
|
|
48
|
+
// create components
|
|
45
49
|
for (let i = 0; i < htmlComponents.length; i++) {
|
|
46
50
|
const html = htmlComponents[i]
|
|
47
|
-
const component =
|
|
51
|
+
const component = parseModule(html.content)
|
|
52
|
+
|
|
48
53
|
components[component.id] = component
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
for (let i = 0; i < htmlPages.length; i++) {
|
|
52
57
|
const html = htmlPages[i]
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
components: resolve(componentsPath)
|
|
58
|
+
const document = parseHTMLDocument(html, {
|
|
59
|
+
pages: pagesPath,
|
|
60
|
+
components: componentsPath
|
|
57
61
|
})
|
|
58
62
|
|
|
63
|
+
for (let i = 0; i < document.customElements.length; i++) {
|
|
64
|
+
const customElement = document.customElements[i]
|
|
65
|
+
const component = await createComponent({
|
|
66
|
+
id: customElement.name,
|
|
67
|
+
values: customElement.attribs,
|
|
68
|
+
customElementSlots: document.customElementSlots,
|
|
69
|
+
components,
|
|
70
|
+
document
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
// replace custom element with component
|
|
74
|
+
customElement.parent.children.splice(customElement.parentChildIndex, 1, ...component.children)
|
|
75
|
+
component.parent = customElement.parent
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// render document
|
|
79
|
+
// @ts-ignore
|
|
80
|
+
const content = render(document.root)
|
|
81
|
+
|
|
59
82
|
if (!dryRun) {
|
|
60
83
|
// get pages sub directory
|
|
61
84
|
const subDir = getSubDirectory(pagesPath, html.parentPath)
|
package/jsconfig.json
CHANGED
package/lib/coralite.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { CoraliteElement, CoraliteTextNode } from '#types'
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* These exports are placeholder for types
|
|
7
|
+
* The HTML module code is run in the `parseScript` function in parse.js
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @type {Object.<string, string>}
|
|
12
|
+
*/
|
|
13
|
+
export const tokens = {}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Defines a Coralite component
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} options
|
|
19
|
+
* @param {string} [options.id] - Optional component id, if not defined, the id will be extracted from the first top level element with the id attribute
|
|
20
|
+
* @param {Object.<string, (string | function)>} options.tokens - A map where keys are token names and values are either strings or functions representing the corresponding tokens' content or behavior.
|
|
21
|
+
* @returns {Promise<Object.<string, string>>}
|
|
22
|
+
*/
|
|
23
|
+
export async function defineComponent (options) {
|
|
24
|
+
/** @type {Object.<string, string>} */
|
|
25
|
+
return {}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Aggregates HTML content from specified paths into a single collection of components.
|
|
30
|
+
*
|
|
31
|
+
* @param {Object} options - Configuration object for the aggregation process
|
|
32
|
+
* @param {string} options.componentId - Unique identifier for the component used for each document
|
|
33
|
+
* @param {string} options.path - The path to aggregate, relative to pages directory
|
|
34
|
+
* @returns {Promise<(CoraliteElement | CoraliteTextNode)[]>}
|
|
35
|
+
*/
|
|
36
|
+
export async function aggregate (options) {
|
|
37
|
+
return []
|
|
38
|
+
}
|
package/lib/get-html.js
CHANGED
|
@@ -7,13 +7,21 @@ import { readdir, readFile } from 'node:fs/promises'
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Get HTML
|
|
10
|
-
* @param {Object} options -
|
|
11
|
-
* @param {string} options.path -
|
|
12
|
-
* @param {boolean} [options.recursive] -
|
|
13
|
-
* @param {string[]} [options.exclude
|
|
14
|
-
* @returns {Promise<HTMLData[]>}
|
|
10
|
+
* @param {Object} options - Options for searching HTML files
|
|
11
|
+
* @param {string} options.path - Path to the directory containing HTML files
|
|
12
|
+
* @param {boolean} [options.recursive=false] - Whether to search recursively in subdirectories
|
|
13
|
+
* @param {string[]} [options.exclude=[]] - Files or directories to exclude from search
|
|
14
|
+
* @returns {Promise<HTMLData[]>} Array of HTML file data including parent path, name, and content
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // Example usage:
|
|
18
|
+
* const htmlFiles = await getHTML({
|
|
19
|
+
* path: 'src',
|
|
20
|
+
* recursive: true,
|
|
21
|
+
* exclude: ['index.html', 'subdir/file2.html']
|
|
22
|
+
* })
|
|
15
23
|
*/
|
|
16
|
-
export default function getHTML ({ path, recursive, exclude = [] }) {
|
|
24
|
+
export default function getHTML ({ path, recursive = false, exclude = [] }) {
|
|
17
25
|
return new Promise((resolve, reject) => {
|
|
18
26
|
const html = []
|
|
19
27
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { join } from 'node:path'
|
|
2
|
+
import getHTML from './get-html.js'
|
|
3
|
+
import { createComponent, parseHTMLMeta } from './parse.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @import { CoraliteTokenOptions, CoraliteModule, CoraliteDocument } from '#types'
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Aggregates HTML content from specified paths into a single collection of components.
|
|
11
|
+
*
|
|
12
|
+
* @param {Object} options - Configuration object for the aggregation process
|
|
13
|
+
* @param {string} options.path - The path to aggregate, relative to pages directory
|
|
14
|
+
* @param {string} options.componentId - Unique identifier for the component
|
|
15
|
+
* @param {boolean} [options.recursive] - Whether to recursively search subdirectories
|
|
16
|
+
* @param {CoraliteTokenOptions} [options.tokens] - Token configuration options
|
|
17
|
+
* @param {Object.<string, string>} values - Default token values
|
|
18
|
+
* @param {Object.<string, CoraliteModule>} components - Available components library
|
|
19
|
+
* @param {CoraliteDocument} document - Current document being processed
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```javascript
|
|
23
|
+
* // Aggregating content from pages under 'components' directory into a component with id 'my-component'
|
|
24
|
+
* aggregate({
|
|
25
|
+
* path: 'button',
|
|
26
|
+
* recursive: true,
|
|
27
|
+
* componentId: 'my-component'
|
|
28
|
+
* }, {
|
|
29
|
+
* className: 'btn'
|
|
30
|
+
* }, components, document);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export async function aggregate (options, values, components, document) {
|
|
34
|
+
const pages = await getHTML({
|
|
35
|
+
path: join(document.path.pages, options.path),
|
|
36
|
+
recursive: options.recursive,
|
|
37
|
+
exclude: [document.name]
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
let result = []
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < pages.length; i++) {
|
|
43
|
+
const page = pages[i]
|
|
44
|
+
const meta = parseHTMLMeta(page.content)
|
|
45
|
+
const pageValues = Object.assign({}, values)
|
|
46
|
+
|
|
47
|
+
for (const key in meta) {
|
|
48
|
+
if (Object.prototype.hasOwnProperty.call(meta, key)) {
|
|
49
|
+
const data = meta[key]
|
|
50
|
+
|
|
51
|
+
for (let i = 0; i < data.length; i++) {
|
|
52
|
+
const item = data[i]
|
|
53
|
+
let suffix = ''
|
|
54
|
+
|
|
55
|
+
if (i > 0) {
|
|
56
|
+
suffix = '_' + i
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
pageValues[item.name + suffix] = item.content
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const component = await createComponent({
|
|
65
|
+
id: options.componentId,
|
|
66
|
+
values: pageValues,
|
|
67
|
+
components,
|
|
68
|
+
document
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
result = result.concat(component.children)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return result
|
|
75
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -1,19 +1,8 @@
|
|
|
1
|
-
import getComponentFromString from './get-component-from-string.js'
|
|
2
1
|
import getHTML from './get-html.js'
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import getMetadataFromDocument from './get-metadata-from-document.js'
|
|
7
|
-
import getSubDirectory from './get-subdirectory.js'
|
|
8
|
-
import evalComputedTokens from './eval-computed-tokens.js'
|
|
2
|
+
|
|
3
|
+
export * from './parse.js'
|
|
4
|
+
export * from './path-utils.js'
|
|
9
5
|
|
|
10
6
|
export {
|
|
11
|
-
evalComputedTokens,
|
|
12
|
-
getSubDirectory,
|
|
13
|
-
getMetadataFromDocument,
|
|
14
|
-
getScriptFromString,
|
|
15
|
-
getTokensFromString,
|
|
16
|
-
getComponentFromString,
|
|
17
|
-
mergeComponentToDocument,
|
|
18
7
|
getHTML
|
|
19
8
|
}
|