@caweb/cli 1.11.1 → 1.12.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.
@@ -9,7 +9,7 @@ import chalk from 'chalk';
9
9
  /**
10
10
  * Internal dependencies
11
11
  */
12
- import { appPath, writeLine } from '../../lib/index.js';
12
+ import { appPath, writeLine, clearLine } from '../../lib/index.js';
13
13
 
14
14
  import {
15
15
  promptForGeneralInfo,
@@ -78,6 +78,7 @@ export default async function createSite({
78
78
  writeLine('You can also edit the configuration file later.', {color: 'cyan', prefix: 'i'});
79
79
 
80
80
  // populate the site data
81
+ // prompt for each section
81
82
  siteData = {
82
83
  ...await promptForGeneralInfo(siteTitle),
83
84
  header: await promptForHeader(),
@@ -93,10 +94,31 @@ export default async function createSite({
93
94
  JSON.stringify( {site:siteData}, null, 4 )
94
95
  );
95
96
 
97
+ // if there is no src directory, create it
98
+ if( ! fs.existsSync( path.join( appPath, 'src' ) ) ) {
99
+ fs.mkdirSync( path.join( appPath, 'src' ) );
100
+
101
+ // create the index.js file
102
+ fs.writeFileSync(
103
+ path.join( appPath, 'src', 'index.js' ),
104
+ `// This is the main entry point for your CAWebPublishing site.\n// You can start coding your site here.\n\nconsole.log('Welcome to your CAWebPublishing site!');`
105
+ );
106
+ }
107
+
108
+ // create media directory if it doesn't exist
109
+ if( ! fs.existsSync( path.join( appPath, 'media' ) ) ) {
110
+ fs.mkdirSync( path.join( appPath, 'media' ) );
111
+ }
112
+
113
+ // clearLines for stored messages
114
+ // clearlines = (6 * 3) + 7
115
+ // (sectionCount * storedMessageLines) + Intro Lines
116
+ clearLine( (6 * 3) + 7 );
117
+
96
118
  writeLine('CAWebPublishing Site Creation Process Complete', {char: '#', borderColor: 'green'});
97
119
  writeLine('You can now start the site by running the following command:', {color: 'cyan', prefix: 'i'});
98
120
  writeLine(`npm run caweb serve`, {color: 'cyan', prefix: 'i'});
99
121
 
100
- spinner.start('CAWebPublishing Site Configuration file saved.');
101
-
122
+ spinner.text = `CAWebPublishing Site Configuration file saved at ${path.join( appPath, 'caweb.json' )}.`;
123
+
102
124
  };
@@ -28,8 +28,7 @@ const headerNav = [
28
28
  "sub": [
29
29
  {
30
30
  "label": "Accessibility",
31
- "url": "https://caweb.cdt.ca.gov/accessibility-2/",
32
- "description": "Accessibility"
31
+ "url": "https://caweb.cdt.ca.gov/accessibility-2/"
33
32
  },
34
33
  ]
35
34
  }
@@ -157,7 +156,7 @@ async function promptForHeader(){
157
156
  }
158
157
 
159
158
  // if navigation is selected, prompt for navigation configurations.
160
- if( features.includes('navigation') ){
159
+ if( features.includes('navigation') ){
161
160
 
162
161
  writeLine('Navigation', {bold: true});
163
162
  writeLine('The Navigation is a set of links that are displayed to navigate your site.', {color: 'cyan', prefix: 'i'});
@@ -184,8 +183,6 @@ async function promptForHeader(){
184
183
  clearLine((header.nav.length * 3) + 2);
185
184
  }
186
185
 
187
- // clear lines
188
- clearLine(6);
189
186
  writeLine('Header Configurations Stored.', {color: 'yellow', char: '#', borderColor: 'yellow'});
190
187
 
191
188
  // return the header object
@@ -230,7 +227,7 @@ async function promptForFooter(){
230
227
 
231
228
  // clear lines for each link plus the link stored message
232
229
  // + 5 for the header and info message
233
- clearLine((footer.nav.length * 3) + 5);
230
+ clearLine((footer.nav.length * 3) + 2);
234
231
 
235
232
  writeLine('Footer Configurations Stored.', {color: 'yellow', char: '#', borderColor: 'yellow'});
236
233
 
@@ -518,15 +515,37 @@ async function promptForGeneralInfo(title){
518
515
  writeLine('General Site Information', {color: 'magenta', char: '#', borderColor: 'magenta'});
519
516
 
520
517
  let info = {
521
- title: await input({
522
- message: 'What is the title of the site?',
523
- default: title,
524
- required: true,
525
- },
526
- {
527
- clearPromptOnDone: true,
528
- }
529
- ).catch(() => {process.exit(1);})
518
+ title: await input({
519
+ message: 'What is the title of the site?',
520
+ default: title,
521
+ required: true,
522
+ },
523
+ {
524
+ clearPromptOnDone: true,
525
+ }
526
+ ).catch(() => {
527
+ // clear lines.
528
+ clearLine(10);
529
+ process.exit(1);
530
+ }),
531
+ domain: await input({
532
+ message: 'What is the domain of the site?',
533
+ default: 'http://localhost',
534
+ validate: (input) => {
535
+ if( ! input.startsWith('http') && ! input.startsWith('https') ){
536
+ return 'Domain must start with http or https.';
537
+ }
538
+ return true;
539
+ }
540
+ },
541
+ {
542
+ clearPromptOnDone: true,
543
+ }
544
+ ).catch(() => {
545
+ // clear lines.
546
+ clearLine(10);
547
+ process.exit(1);
548
+ }),
530
549
  };
531
550
 
532
551
  // clear lines.
@@ -0,0 +1,68 @@
1
+ import { parse } from 'node-html-parser';
2
+ import { writeLine } from '../../lib/index.js';
3
+
4
+ /**
5
+ * Validates the HTML of a page.
6
+ * @param {JSDOM} document - Window document from JSDOM.
7
+ * @returns {boolean} - Returns true if the HTML is valid, false otherwise.
8
+ */
9
+ function validatePage( document ){
10
+ let mainContent = document.querySelector( '#page-container #main-content' );
11
+
12
+ // Check if document doesn't have a #page-container #main-content
13
+ if( ! mainContent ){
14
+ throw new Error("The page does not have a #page-container #main-content.");
15
+ }
16
+
17
+ let mainContentJson = parse( mainContent.innerHTML );
18
+ let mainJson = ''
19
+ let asideJson = '';
20
+
21
+ /**
22
+ * Main content is allowed 2 elements
23
+ * - main - renders the main content
24
+ * - aside - renders the sidebar content
25
+ */
26
+ for( const element of mainContentJson.children ){
27
+ if( element.tagName !== 'MAIN' && element.tagName !== 'ASIDE' ){
28
+ throw new Error("The main content must only contain <main> and <aside> elements.");
29
+ }else if( element.tagName === 'MAIN' ){
30
+ mainJson = element
31
+ }else if( element.tagName === 'ASIDE' ){
32
+ asideJson = element
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Main should only consist of <div> elements.
38
+ * - .container-fluid - Used for full width containers.
39
+ * - .container - used for standard containers.
40
+ * -- Should only consist of div.row
41
+ * ---- Should only consist of div.col-#
42
+ * ------ All content should be in a column
43
+ */
44
+ for( const element of mainJson.children ){
45
+ if( element.tagName !== 'DIV' ){
46
+ throw new Error("The <main> element must only contain <div> elements.");
47
+ }else if( ! element.classList.contains( 'container-fluid' ) && ! element.classList.contains( 'container' ) ){
48
+ throw new Error("The <main> element must only contain <div> elements with class 'container-fluid' or 'container'.");
49
+ }else if( element.classList.contains( 'container' ) ){
50
+ for( const row of element.children ){
51
+ if( row.tagName !== 'DIV' || ! row.classList.contains( 'row' ) ){
52
+ throw new Error("The <div> element with class 'container' must only contain <div> elements with class 'row'.");
53
+ }else{
54
+ for( const col of row.children ){
55
+ if( col.tagName !== 'DIV' || ! col.classList.toString().match( /col[-\d]*/g ) ){
56
+ throw new Error("The <div> element with class 'row' must only contain <div> elements with class 'col-#'.");
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ }
64
+
65
+
66
+ }
67
+
68
+ export default validatePage;