coralite 0.11.0 → 0.11.2

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/README.md CHANGED
@@ -3,7 +3,7 @@
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
  <p style="text-align:center;">
6
- <img src="./docs/images/logo.png" alt="Animated gif of how to use Coralite" style="max-width: 100%; width: auto;filter: drop-shadow(rgba(0,0,0,0.2) 0px 0px 0.75rem)">
6
+ <img src="https://codeberg.org/tjdavid/coralite/media/branch/main/docs/images/logo.png" alt="Coralite logo" style="max-width: 100%; width: auto;filter: drop-shadow(rgba(0,0,0,0.2) 0px 0px 0.75rem)">
7
7
  </p>
8
8
 
9
9
  - Getting started
@@ -49,14 +49,14 @@ Replace `[options]` with the desired flags and arguments.
49
49
 
50
50
  To generate a website using Coralite, you must provide three essential options:
51
51
 
52
- - **-t or --templates**: The path to your templates directory containing reusable UI elements (e.g., `-c ./src/templates`).
53
- - **-p or --pages**: The path to your pages directory where static HTML files reside (e.g., `-p ./src/pages`).
54
- - **--output or -o**: The output directory for the generated site (e.g., `--output ./dist`).
52
+ - **-t or --templates**: The path to your templates directory containing reusable UI elements (e.g., `-t src/templates`).
53
+ - **-p or --pages**: The path to your pages directory where static HTML files reside (e.g., `-p src/pages`).
54
+ - **--output or -o**: The output directory for the generated site (e.g., `--output dist`).
55
55
 
56
56
  Here's an example of how these options might look:
57
57
 
58
58
  ```bash
59
- coralite --templates ./path/to/templates --pages ./path/to/pages --output ./dist
59
+ coralite --templates path/to/templates --pages path/to/pages --output dist
60
60
  ```
61
61
 
62
62
  ## Optional Options
@@ -66,20 +66,22 @@ coralite --templates ./path/to/templates --pages ./path/to/pages --output ./dist
66
66
  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:
67
67
 
68
68
  ```bash
69
- coralite --templates ./path/to/templates --pages ./path/to/pages --output ./dist --dry-run
69
+ coralite --templates path/to/templates --pages path/to/pages --output dist --dry-run
70
70
  ```
71
71
 
72
72
  ## Troubleshooting
73
73
 
74
74
 
75
- Coralite uses **ECMAScript Modules** which requires to run Node.js with the **`--experimental-vm-modules`** option enabled.
75
+ Coralite uses **ECMAScript Modules** and **Import meta resolve** which requires to run Node.js with the **`--experimental-vm-modules`** and **`--experimental-import-meta-resolve`** option enabled.
76
76
 
77
77
  ```bash
78
- node --experimental-vm-modules node_modules/coralite/bin/coralite.js [options]
78
+ node --experimental-vm-modules --experimental-import-meta-resolve node_modules/coralite/bin/coralite.js [options]
79
79
  ```
80
80
 
81
+ If you require your templates to import
82
+
81
83
  or using NODE_OPTIONS
82
84
 
83
85
  ```bash
84
- NODE_OPTIONS=--experimental-vm-modules coralite [options]
86
+ NODE_OPTIONS="--experimental-vm-modules --experimental-import-meta-resolve" coralite [options]
85
87
  ```
package/bin/coralite.js CHANGED
@@ -2,12 +2,10 @@
2
2
 
3
3
  import { getPkg, Coralite } from '#lib'
4
4
  import { Command } from 'commander'
5
- import { join } from 'node:path'
6
- import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
7
5
  import kleur from 'kleur'
8
6
  import { loadConfig } from '../lib/loader.js'
9
7
 
10
- // Remove all Node warnings before doing anything else
8
+ // remove all Node warnings before doing anything else
11
9
  process.removeAllListeners('warning')
12
10
 
13
11
  const pkg = await getPkg()
@@ -41,6 +39,7 @@ const coraliteOptions = {
41
39
  plugins: []
42
40
  }
43
41
 
42
+ // process ignore-attribute key=value pairs
44
43
  for (let i = 0; i < options.ignoreAttribute.length; i++) {
45
44
  const pair = options.ignoreAttribute[i].split('=')
46
45
 
@@ -54,19 +53,23 @@ for (let i = 0; i < options.ignoreAttribute.length; i++) {
54
53
  })
55
54
  }
56
55
 
56
+ // merge plugins from config file into coraliteOptions
57
57
  if (config && config.plugins) {
58
58
  coraliteOptions.plugins = coraliteOptions.plugins.concat(config.plugins)
59
59
  }
60
60
 
61
+ // initializes Coralite with the provided options and compiles documents
61
62
  const coralite = new Coralite(coraliteOptions)
62
- const collection = await coralite.compile()
63
+ // compiles all pages using Coralite
64
+ const documents = await coralite.compile()
63
65
 
64
66
  if (options.dryRun) {
67
+ // print document details without saving files
65
68
  const PAD = ' '
66
69
  const border = '─'.repeat(Math.min(process.stdout.columns, 36) / 2)
67
70
 
68
- for (let i = 0; i < collection.length; i++) {
69
- const document = collection[i]
71
+ for (let i = 0; i < documents.length; i++) {
72
+ const document = documents[i]
70
73
 
71
74
  process.stdout.write('\n' + PAD + kleur.green('Document is ready!\n\n'))
72
75
  process.stdout.write(PAD + `${kleur.bold('- Path:')} ${document.item.path.pathname}\n`)
@@ -76,17 +79,6 @@ if (options.dryRun) {
76
79
  process.stdout.write('\n\n' + border + kleur.inverse(' Content end ') + border + '\n')
77
80
  }
78
81
  } else {
79
- for (let i = 0; i < collection.length; i++) {
80
- const document = collection[i]
81
- const dir = join(output, document.item.path.dirname)
82
-
83
- if (!existsSync(dir)) {
84
- // create directory
85
- mkdirSync(dir, {
86
- recursive: true
87
- })
88
- }
89
-
90
- writeFileSync(join(output, document.item.path.pathname), document.html)
91
- }
82
+ // save the generated documents to output directory
83
+ await coralite.save(documents, output)
92
84
  }
package/changelog.md CHANGED
@@ -1,11 +1,52 @@
1
1
  # 🎁 Complete Release History
2
2
 
3
+ ## Release: `v0.11.2`
4
+
5
+ ### Changes from `v0.11.1` to `v0.11.2`
6
+
7
+ - b9d8c37 (HEAD -> main, tag: v0.11.2) chore: bump version - ([Thomas David](https://codeberg.org/tjdavid))
8
+ - e427d7d (origin/main) style: update comment formatting consistency - ([Thomas David](https://codeberg.org/tjdavid))
9
+ - 707c462 types: add ts-ignore for script.namespace.default - ([Thomas David](https://codeberg.org/tjdavid))
10
+ - 3e4df9a fix: correctly skip directive nodes in replaceToken function - ([Thomas David](https://codeberg.org/tjdavid))
11
+ - bed8aa6 docs: update parameter names and type annotations - ([Thomas David](https://codeberg.org/tjdavid))
12
+ - c065e9a fix: Improve error messages for template directory and module export issues - ([Thomas David](https://codeberg.org/tjdavid))
13
+ - a76bc28 feat: add save method to export processed documents as HTML files - ([Thomas David](https://codeberg.org/tjdavid))
14
+ - cc65461 refactor: use coralite.save instead of manual file operations - ([Thomas David](https://codeberg.org/tjdavid))
15
+ - 48f180f docs: add inline comments - ([Thomas David](https://codeberg.org/tjdavid))
16
+
17
+ ### Metadata
18
+ ```
19
+ This version -------- v0.11.2
20
+ Previous version ---- v0.11.1
21
+ Total commits ------- 9
22
+ ```
23
+
24
+ ## Release: `v0.11.1`
25
+
26
+ ### Changes from `v0.11.0` to `v0.11.1`
27
+
28
+ - c0ab58b (tag: v0.11.1) docs: add experimental-import-meta-resolve flag to Node.js runtime options - ([Thomas David](https://codeberg.org/tjdavid))
29
+ - 5675297 chore: bump version - ([Thomas David](https://codeberg.org/tjdavid))
30
+ - 9ca30e8 build: update minimum required Node.js version - ([Thomas David](https://codeberg.org/tjdavid))
31
+ - 7b40a42 fix: script identifier path - ([Thomas David](https://codeberg.org/tjdavid))
32
+ - a9300f7 docs: update example commands in readme.md - ([Thomas David](https://codeberg.org/tjdavid))
33
+ - b128309 npmignore codeberg ci - ([Thomas David](https://codeberg.org/tjdavid))
34
+ - 398737d docs: use absolute path for logo - ([Thomas David](https://codeberg.org/tjdavid))
35
+ - 68eb2c7 docs: update readme image to logo.png - ([Thomas David](https://codeberg.org/tjdavid))
36
+
37
+ ### Metadata
38
+ ```
39
+ This version -------- v0.11.1
40
+ Previous version ---- v0.11.0
41
+ Total commits ------- 8
42
+ ```
43
+
3
44
  ## Release: `v0.11.0`
4
45
 
5
46
  ### Changes from `v0.10.0` to `v0.11.0`
6
47
 
7
- - 56f6474 (HEAD -> main, tag: v0.11.0) chore: bump version to 0.11.0 - ([Thomas David](https://codeberg.org/tjdavid))
8
- - 29b2c6a (origin/main) chore: Remove unused test-unit script - ([Thomas David](https://codeberg.org/tjdavid))
48
+ - 56f6474 (tag: v0.11.0) chore: bump version to 0.11.0 - ([Thomas David](https://codeberg.org/tjdavid))
49
+ - 29b2c6a chore: Remove unused test-unit script - ([Thomas David](https://codeberg.org/tjdavid))
9
50
  - 38a7c85 test: add test for cast names from local JSON file - ([Thomas David](https://codeberg.org/tjdavid))
10
51
  - 7605e09 docs: update ignoreByAttribute config format to use objects - ([Thomas David](https://codeberg.org/tjdavid))
11
52
  - 8e13c2d types: update ignoreByAttribute to use object structure - ([Thomas David](https://codeberg.org/tjdavid))
@@ -1138,6 +1179,6 @@ Total commits ------- 86
1138
1179
 
1139
1180
  ## Summary
1140
1181
  ```
1141
- Total releases ------ 25
1142
- Total commits ------- 457
1182
+ Total releases ------ 27
1183
+ Total commits ------- 474
1143
1184
  ```
package/lib/collection.js CHANGED
@@ -72,7 +72,7 @@ CoraliteCollection.prototype.setItem = function (value) {
72
72
  const documentValue = value
73
73
 
74
74
  if (!originalValue) {
75
- // Handle pre-set hook if defined
75
+ // handle pre-set hook if defined
76
76
  if (typeof this._onSet === 'function') {
77
77
  const result = this._onSet(value)
78
78
 
@@ -82,21 +82,21 @@ CoraliteCollection.prototype.setItem = function (value) {
82
82
  documentValue.type = result.type
83
83
  }
84
84
 
85
- // Update collection using ID from hook result if available
85
+ // update collection using ID from hook result if available
86
86
  if (typeof result.id === 'string' && result.id) {
87
87
  this.collection[result.id] = documentValue
88
88
  }
89
89
  }
90
90
 
91
- // Always update the collection with current pathname
91
+ // always update the collection with current pathname
92
92
  this.collection[pathname] = documentValue
93
93
 
94
- // Initialize directory list if it doesn't exist
94
+ // initialize directory list if it doesn't exist
95
95
  if (!this.listByPath[dirname]) {
96
96
  this.listByPath[dirname] = []
97
97
  }
98
98
 
99
- // Add to both directory-specific and general lists
99
+ // add to both directory-specific and general lists
100
100
  this.listByPath[dirname].push(documentValue)
101
101
  this.list.push(documentValue)
102
102
  } else {
@@ -122,12 +122,12 @@ CoraliteCollection.prototype.deleteItem = function (value) {
122
122
  }
123
123
 
124
124
  if (typeof value !== 'string' && value.path) {
125
- // If the input is an HTMLData object, extract its pathname and directory name
125
+ // if the input is an HTMLData object, extract its pathname and directory name
126
126
  pathname = value.path.pathname
127
127
  dirname = value.path.dirname
128
128
  valuesByPath = this.listByPath[dirname]
129
129
  } else if (pathname && typeof pathname == 'string') {
130
- // If the input is a string, use it as the pathname and determine the directory name
130
+ // if the input is a string, use it as the pathname and determine the directory name
131
131
  dirname = path.dirname(pathname)
132
132
  valuesByPath = this.listByPath[dirname]
133
133
  } else {
@@ -141,10 +141,10 @@ CoraliteCollection.prototype.deleteItem = function (value) {
141
141
  const originalValue = this.collection[pathname]
142
142
 
143
143
  if (originalValue) {
144
- // Remove the document from the collection
144
+ // remove the document from the collection
145
145
  delete this.collection[pathname]
146
146
 
147
- // Find and remove the document from the list and by-path grouping
147
+ // find and remove the document from the list and by-path grouping
148
148
  const listIndex = this.list.indexOf(originalValue)
149
149
  const pathIndex = valuesByPath.indexOf(originalValue)
150
150
 
@@ -164,7 +164,7 @@ CoraliteCollection.prototype.updateItem = function (value) {
164
164
  const originalValue = this.collection[value.path.pathname]
165
165
 
166
166
  if (!originalValue) {
167
- // If the document does not exist, add it using the set method
167
+ // if the document does not exist, add it using the set method
168
168
  this.setItem(value)
169
169
  } else {
170
170
  if (typeof this._onUpdate === 'function') {
package/lib/coralite.js CHANGED
@@ -5,6 +5,7 @@ import { resolve, join } from 'node:path'
5
5
  import { createContext, SourceTextModule } from 'node:vm'
6
6
  import { defineComponent } from '#plugins'
7
7
  import { existsSync } from 'node:fs'
8
+ import { mkdir, writeFile } from 'node:fs/promises'
8
9
 
9
10
  /**
10
11
  * @import {
@@ -22,6 +23,7 @@ import { existsSync } from 'node:fs'
22
23
  * CoralitePluginInstance,
23
24
  * CoraliteCollectionEventSet,
24
25
  * IgnoreByAttribute} from '#types'
26
+ * @import CoraliteCollection from './collection.js'
25
27
  * @import {Module} from 'node:vm'
26
28
  */
27
29
 
@@ -50,9 +52,7 @@ export function Coralite ({
50
52
  templates,
51
53
  pages
52
54
  }
53
-
54
55
  this.values = {}
55
-
56
56
  this.templates = getHtmlFiles({
57
57
  path: templates,
58
58
  recursive: true,
@@ -149,6 +149,7 @@ export function Coralite ({
149
149
  }
150
150
  }
151
151
 
152
+ /** @type {CoraliteCollection} */
152
153
  this.pages = getHtmlFiles({
153
154
  path: pages,
154
155
  recursive: true,
@@ -265,14 +266,10 @@ export function Coralite ({
265
266
  * and returns rendered results with performance metrics.
266
267
  *
267
268
  * @param {string | string[]} [path] - Path to a single page or array of page paths relative to the pages directory. If omitted, compiles all pages.
268
- * @return {Promise<Array<CoraliteResult>>} - An array of objects containing:
269
- * - item: The compiled document object
270
- * - html: Rendered HTML string
271
- * - duration: Total render time in milliseconds (if performance measurement is enabled)
269
+ * @return {Promise<Array<CoraliteResult>>}
272
270
  */
273
271
  Coralite.prototype.compile = async function (path) {
274
272
  const startTime = performance.now()
275
-
276
273
  this._currentRenderQueue = this.pages.list.slice()
277
274
 
278
275
  if (Array.isArray(path)) {
@@ -377,6 +374,35 @@ Coralite.prototype.compile = async function (path) {
377
374
  return results
378
375
  }
379
376
 
377
+ /**
378
+ * Saves processed documents as HTML files to the specified output directory.
379
+ * @param {Array<CoraliteResult>} documents - Array of document objects containing metadata and HTML content
380
+ * @param {string} output - Base directory path where generated HTML files will be saved
381
+ */
382
+ Coralite.prototype.save = async function (documents, output) {
383
+ try {
384
+ // create a list of promises for writing each document's HTML file
385
+ const writePromises = documents.map(async (document) => {
386
+ const dir = join(output, document.item.path.dirname)
387
+ const filename = join(dir, document.item.path.filename)
388
+
389
+ // ensure the directory exists
390
+ await mkdir(dir, { recursive: true })
391
+
392
+ // write the HTML content to the file
393
+ await writeFile(filename, document.html)
394
+
395
+ return filename
396
+ })
397
+
398
+ // wait for all files to be written
399
+ const outputFiles = await Promise.all(writePromises)
400
+ return outputFiles
401
+ } catch (error) {
402
+ throw error
403
+ }
404
+ }
405
+
380
406
  /**
381
407
  * Renders the provided node or array of nodes using the render function.
382
408
  * This method serves as an internal utility to handle the rendering process.
@@ -396,22 +422,22 @@ Coralite.prototype._render = function (root) {
396
422
  * @returns {string[]} An array of page paths linked to the custom element template.
397
423
  */
398
424
  Coralite.prototype.getPagePathsUsingCustomElement = function (path) {
399
- // Normalize path by removing the templates directory prefix
425
+ // normalize path by removing the templates directory prefix
400
426
  if (path.startsWith(this.path.templates)) {
401
427
  path = path.substring(this.path.templates.length + 1)
402
428
  }
403
429
 
404
- // Retrieve the template item from the templates collection
430
+ // retrieve the template item from the templates collection
405
431
  const item = this.templates.getItem(path)
406
432
  const pages = []
407
433
 
408
- // If template exists, collect associated page paths
434
+ // if template exists, collect associated page paths
409
435
  if (item) {
410
436
  const id = this._childCustomElements[item.result.id] || item.result.id
411
437
  const pageCustomElements = this._pageCustomElements[id]
412
438
 
413
439
  if (pageCustomElements) {
414
- // Iterate over custom element paths linked to this template
440
+ // iterate over custom element paths linked to this template
415
441
  pageCustomElements.forEach(path => {
416
442
  pages.push(path)
417
443
  })
@@ -454,10 +480,10 @@ Coralite.prototype.addRenderQueue = function (value) {
454
480
  *
455
481
  * @example
456
482
  * ```
457
- * // Example usage:
483
+ * // example usage:
458
484
  * const component = await createComponent({
459
485
  * id: 'my-component',
460
- * values: {
486
+ * tokens: {
461
487
  * 'some-value': 'value-for-template'
462
488
  * },
463
489
  * components: {
@@ -490,7 +516,7 @@ Coralite.prototype.createComponent = async function ({
490
516
  values = Object.assign(values, element.attribs)
491
517
  }
492
518
 
493
- // Convert object keys to camel case format for consistent naming conventions
519
+ // convert object keys to camel case format for consistent naming conventions
494
520
  values = cleanKeys(values)
495
521
  }
496
522
 
@@ -734,6 +760,7 @@ Coralite.prototype._evaluate = async function ({
734
760
  contextId
735
761
  }) {
736
762
  this._currentSourceContextId = contextId
763
+
737
764
  const context = {
738
765
  ...this._sourceContext,
739
766
  document,
@@ -744,7 +771,7 @@ Coralite.prototype._evaluate = async function ({
744
771
  }
745
772
 
746
773
  this._sourceContextInstances[contextId] = context
747
- // Create a new context object with the provided context and global objects
774
+ // create a new context object with the provided context and global objects
748
775
  const contextifiedObject = createContext({
749
776
  console: globalThis.console,
750
777
  crypto: globalThis.crypto,
@@ -753,22 +780,22 @@ Coralite.prototype._evaluate = async function ({
753
780
  const template = this.templates.getItem(module.id)
754
781
  let parentPath = template.path.dirname
755
782
 
756
- // Resolve the parent path of the template
783
+ // resolve the parent path of the template
757
784
  if (!existsSync(parentPath)) {
758
785
  parentPath = resolve(join(this.path.templates, template.path.dirname))
759
786
 
760
787
  if (!existsSync(parentPath)) {
761
- throw new Error('Unexpected template pathname: ' + parentPath)
788
+ throw new Error('Template directory not found: ' + parentPath)
762
789
  }
763
790
  }
764
791
 
765
- // Create a new source text module with the provided script content, configuration options, and context
792
+ // create a new source text module with the provided script content, configuration options, and context
766
793
  const script = new SourceTextModule(module.script, {
767
794
  initializeImportMeta (meta) {
768
795
  meta.url = process.cwd()
769
796
  },
770
797
  lineOffset: module.lineOffset,
771
- identifier: parentPath,
798
+ identifier: join(parentPath, template.path.filename),
772
799
  context: contextifiedObject
773
800
  })
774
801
 
@@ -776,20 +803,17 @@ Coralite.prototype._evaluate = async function ({
776
803
 
777
804
  await script.link(linker)
778
805
 
779
- // Evaluate the module to execute its content
806
+ // evaluate the module to execute its content
780
807
  await script.evaluate()
781
808
 
782
809
  // @ts-ignore
783
810
  if (script.namespace.default) {
784
- try {
785
- return await script.namespace.default
786
- } catch (err) {
787
- throw err
788
- }
811
+ // @ts-ignore
812
+ return await script.namespace.default
789
813
  }
790
814
 
791
- // Throw an error if no default export was found
792
- throw new Error('Script found module export: "' + module.id + '"')
815
+ // throw an error if no default export was found
816
+ throw new Error(`Module "${module.id}" has no default export`)
793
817
  }
794
818
 
795
819
  /**
@@ -871,7 +895,7 @@ function replaceToken ({
871
895
  for (let i = 0; i < value.length; i++) {
872
896
  const child = value[i]
873
897
 
874
- if (typeof child !== 'string') {
898
+ if (typeof child !== 'string' && child.type !== 'directive') {
875
899
  // update child parent
876
900
  child.parent = node.parent
877
901
  children.push(child)
package/lib/html.js CHANGED
@@ -22,7 +22,7 @@ import CoraliteCollection from './collection.js'
22
22
  * @returns {CoraliteCollection} Array of HTML file data including parent path, name, and content
23
23
  *
24
24
  * @example
25
- * // Example usage:
25
+ * // example usage:
26
26
  * const htmlFiles = await getHtmlFiles({
27
27
  * path: 'src',
28
28
  * recursive: true,
package/lib/parse.js CHANGED
@@ -136,7 +136,7 @@ export function parseHTML (string, ignoreByAttribute) {
136
136
  /** @type {CoraliteModuleValues} */
137
137
  const meta = {}
138
138
  const prefix = '$'
139
- // Process metadata and populate values for rendering
139
+ // process metadata and populate values for rendering
140
140
  for (const key in metadata) {
141
141
  if (Object.prototype.hasOwnProperty.call(metadata, key)) {
142
142
  const data = metadata[key]
@@ -144,7 +144,7 @@ export function parseHTML (string, ignoreByAttribute) {
144
144
 
145
145
  if (Array.isArray(data)) {
146
146
  let prefixName
147
- // Handle multiple metadata items as list
147
+ // handle multiple metadata items as list
148
148
  for (let i = 0; i < data.length; i++) {
149
149
  const item = data[i]
150
150
  let name = prefix + item.name
@@ -188,13 +188,13 @@ export function parseHTML (string, ignoreByAttribute) {
188
188
  *
189
189
  * @example
190
190
  * ```
191
- * // Example usage:
191
+ * // example usage:
192
192
  * const html = `<template id="home">
193
193
  * <slot name="default">Hello</slot>
194
194
  * </template>`;
195
195
  * const module = parseModule(html, { ignoreByAttribute: [] });
196
196
  *
197
- * // Module object structure will be:
197
+ * // module object structure will be:
198
198
  * //{
199
199
  * // id: 'home',
200
200
  * // template: { ... },
@@ -408,10 +408,10 @@ function addMetadata (meta, name, content) {
408
408
  let entry = meta[name]
409
409
 
410
410
  if (!entry) {
411
- // If the metadata key does not exist, initialize it with the provided content.
411
+ // if the metadata key does not exist, initialize it with the provided content.
412
412
  meta[name] = content
413
413
  } else {
414
- // If the existing value is not an array, convert it into an array containing a single object
414
+ // if the existing value is not an array, convert it into an array containing a single object
415
415
  // with the name and content. This allows for handling multiple values under the same metadata key.
416
416
  if (!Array.isArray(entry)) {
417
417
  meta[name] = [{
@@ -420,8 +420,8 @@ function addMetadata (meta, name, content) {
420
420
  }]
421
421
  entry = meta[name]
422
422
  }
423
- // Add the new content to the array as a new object, preserving existing entries.
424
- // This is useful for adding multiple values (e.g., Open Graph metadata) under the same key.
423
+ // add the new content to the array as a new object, preserving existing entries.
424
+ // this is useful for adding multiple values (e.g., Open Graph metadata) under the same key.
425
425
  entry.push({
426
426
  name,
427
427
  content
@@ -42,8 +42,6 @@ function isCoralitePageItem (obj) {
42
42
  return isObject(obj) && obj.hasOwnProperty('path') && typeof obj.content === 'string'
43
43
  }
44
44
 
45
-
46
- // Export the functions (if using modules) - important for reusability
47
45
  export {
48
46
  isCoralitePageItem,
49
47
  isCoraliteElement,
package/lib/utils.js CHANGED
@@ -6,7 +6,7 @@ import { readFile } from 'node:fs/promises'
6
6
  * @returns {string} - The camelCase version of the string
7
7
  */
8
8
  function kebabToCamel (str) {
9
- // Replace each dash followed by a letter with the uppercase version of the letter
9
+ // replace each dash followed by a letter with the uppercase version of the letter
10
10
  return str.replace(/[-|:]([a-z])/g, function (match, letter) {
11
11
  return letter.toUpperCase()
12
12
  })
@@ -23,7 +23,7 @@ export function cleanKeys (object) {
23
23
 
24
24
  for (const key in object) {
25
25
  if (Object.prototype.hasOwnProperty.call(object, key)) {
26
- // Convert the kebab-case key to camelCase and assign the value to the new object
26
+ // convert the kebab-case key to camelCase and assign the value to the new object
27
27
  result[kebabToCamel(key)] = object[key]
28
28
  }
29
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coralite",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "description": "HTML modules static site generator",
5
5
  "main": "./lib/coralite.js",
6
6
  "type": "module",
@@ -72,7 +72,7 @@
72
72
  "sirv-cli": "^3.0.0"
73
73
  },
74
74
  "engines": {
75
- "node": ">=18"
75
+ "node": ">=18.19.0"
76
76
  },
77
77
  "dependencies": {
78
78
  "commander": "^13.0.0",
@@ -58,7 +58,7 @@ export const defineComponent = createPlugin({
58
58
  } else {
59
59
  for (let i = 0; i < result.customElements.length; i++) {
60
60
  const customElement = result.customElements[i]
61
- // Create a component instance from the custom element and its attributes
61
+ // create a component instance from the custom element and its attributes
62
62
  const component = await this.createComponent({
63
63
  id: customElement.name,
64
64
  values,
@@ -93,7 +93,7 @@ export const defineComponent = createPlugin({
93
93
  if (result.root.children.length) {
94
94
  for (let i = 0; i < result.customElements.length; i++) {
95
95
  const customElement = result.customElements[i]
96
- // Create a component instance from the custom element and its attributes
96
+ // create a component instance from the custom element and its attributes
97
97
  const component = await this.createComponent({
98
98
  id: customElement.name,
99
99
  values,
@@ -194,14 +194,14 @@ export const defineComponent = createPlugin({
194
194
  * @param {CoraliteElement} element - The target element to replace the tokens with.
195
195
  */
196
196
  async function replaceCustomElementWithTemplate (coraliteElement, element) {
197
- // Update parent references for new children to maintain the correct structure in the document
197
+ // update parent references for new children to maintain the correct structure in the document
198
198
  for (let i = 0; i < element.children.length; i++) {
199
199
  element.children[i].parent = coraliteElement.parent
200
200
  }
201
201
 
202
- // Determine the index of the original custom element within its parent's child list
202
+ // determine the index of the original custom element within its parent's child list
203
203
  const index = coraliteElement.parent.children.indexOf(coraliteElement, coraliteElement.parentChildIndex)
204
204
 
205
- // Replace the custom element with its template children in the document structure
205
+ // replace the custom element with its template children in the document structure
206
206
  coraliteElement.parent.children.splice(index, 1, ...element.children)
207
207
  }
@@ -1,48 +0,0 @@
1
- name: Publish
2
-
3
- on:
4
- release:
5
- types: [created]
6
-
7
- jobs:
8
- test:
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
- - name: Test
33
- run: pnpm run test-e2e
34
-
35
-
36
- publish-npm:
37
- needs: test
38
- runs-on: ubuntu-latest
39
- steps:
40
- - uses: actions/checkout@v4
41
- - uses: actions/setup-node@v4
42
- with:
43
- node-version: 22
44
- registry-url: https://registry.npmjs.org/
45
- - run: npm publish
46
- env:
47
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
48
-
@@ -1,48 +0,0 @@
1
- name: Test e2e
2
-
3
- on:
4
- - push
5
- - pull_request
6
-
7
- jobs:
8
- test:
9
- timeout-minutes: 60
10
- runs-on: ubuntu-latest
11
-
12
- steps:
13
- - name: Checkout
14
- uses: actions/checkout@v4
15
-
16
- - uses: pnpm/action-setup@v4
17
- name: Install pnpm
18
- with:
19
- version: 9
20
- run_install: false
21
-
22
- - name: Install Node.js
23
- uses: actions/setup-node@v4
24
- with:
25
- node-version: 22
26
- cache: "pnpm"
27
-
28
- - name: Install dependencies
29
- run: pnpm install
30
-
31
- - name: Add symlink
32
- run: pnpm link
33
-
34
- - name: Build HTML from templates
35
- run: pnpm run html
36
-
37
- - name: Install Playwright Browser
38
- run: pnpm exec playwright install firefox --with-deps
39
-
40
- - name: Run Playwright tests
41
- run: pnpm exec playwright test
42
-
43
- - uses: actions/upload-artifact@v4
44
- if: ${{ !cancelled() }}
45
- with:
46
- name: playwright-report
47
- path: playwright-report/
48
- retention-days: 30
@@ -1,58 +0,0 @@
1
- name: Test script
2
-
3
- on:
4
- - push
5
- - pull_request
6
-
7
- jobs:
8
- linux:
9
- runs-on: ubuntu-latest
10
-
11
- steps:
12
- - name: Checkout
13
- uses: actions/checkout@v4
14
-
15
- - uses: pnpm/action-setup@v4
16
- name: Install pnpm
17
- with:
18
- version: 9
19
- run_install: false
20
-
21
- - name: Install Node.js
22
- uses: actions/setup-node@v4
23
- with:
24
- node-version: 22
25
- cache: "pnpm"
26
-
27
- - name: Install dependencies
28
- run: pnpm install
29
-
30
- - name: Build HTML from templates
31
- run: pnpm run html
32
- macos:
33
- runs-on: macos-15
34
-
35
- steps:
36
- - name: Checkout
37
- uses: actions/checkout@v4
38
-
39
- - uses: pnpm/action-setup@v4
40
- name: Install pnpm
41
- with:
42
- version: 9
43
- run_install: false
44
-
45
- - name: Install Node.js
46
- uses: actions/setup-node@v4
47
- with:
48
- node-version: 22
49
- cache: "pnpm"
50
-
51
- - name: Install dependencies
52
- run: pnpm install
53
-
54
- - name: Add symlink
55
- run: pnpm link
56
-
57
- - name: Build HTML from templates
58
- run: pnpm run html