@haxtheweb/create 10.0.4 → 10.0.6

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
@@ -22,6 +22,7 @@ hax start
22
22
  - `hax webcomponent my-element --y` - Make a new HAX capable, i18n wired, Design system (DDD) driven web component
23
23
  - if in a monorepo root, will place in correct location / inherit settings
24
24
  - `hax site mysite --y` - create a new HAXsite (HAXcms, single site)
25
+ - `hax audit` - Audits web components for compliance with DDD (HAX design system)
25
26
 
26
27
  ## --help
27
28
  Run `hax help` or `hax webcomponent --help` or `hax site --help` for up-to-date listing
@@ -30,53 +31,74 @@ Usage: hax [options] [command]
30
31
 
31
32
  Options:
32
33
  --
33
- --v Verbose output for developers
34
- --path <char> where to perform operation
35
- --npm-client <char> npm client to use (must be installed) npm,
36
- yarn, pnpm (default: "npm")
37
- --y yes to all questions
38
- --skip skip frills like animations
39
- --auto yes to all questions, alias of y
40
- --org <char> organization for package.json
41
- --author <char> author for site / package.json
42
- --import-site <char> URL of site to import
43
- --node-op <char> node operation to perform
44
- --item-id <char> node ID to operate on
45
- --name <char> name of the project
46
- --domain <char> published domain name
47
- --title <char> Title
48
- --content <char> Page content
49
- --slug <char> Path (slug)
50
- --published <char> Publishing status
51
- --tags <char> Tags
52
- --parent <char> Parent
53
- --order <char> Order
54
- --theme <char> Theme
55
- --hide-in-menu <char> Hide in menu
56
- -h, --help display help for command
34
+ --v Verbose output
35
+ --debug Output for developers
36
+ --format <char> Output format; json (default), yaml
37
+ --path <char> where to perform operation
38
+ --npm-client <char> npm client to use (must be installed) npm,
39
+ yarn, pnpm (default: "npm")
40
+ --y yes to all questions
41
+ --skip skip frills like animations
42
+ --quiet remove console logging
43
+ --auto yes to all questions, alias of y
44
+ --no-i prevent interactions / sub-process, good for
45
+ scripting
46
+ --to-file <char> redirect command output to a file
47
+ --no-extras skip all extra / automatic command processing
48
+ --root <char> root location to execute the command from
49
+ --org <char> organization for package.json
50
+ --author <char> author for site / package.json
51
+ --writeHaxProperties Write haxProperties for the element
52
+ --import-site <char> URL of site to import
53
+ --import-structure <char> import method to use:
54
+ pressbooksToSite
55
+ elmslnToSite
56
+ haxcmsToSite
57
+ notionToSite
58
+ gitbookToSite
59
+ evolutionToSite
60
+ htmlToSite
61
+ docxToSite
62
+ --node-op <char> node operation to perform
63
+ --item-id <char> node ID to operate on
64
+ --name <char> name of the project
65
+ --domain <char> published domain name
66
+ --title-scrape <char> CSS Selector for `title` in resource
67
+ --content-scrape <char> CSS Selector for `body` in resource
68
+ --items-import <char> import items from a file / site
69
+ --recipe <char> path to recipe file
70
+ --custom-theme-name <char> custom theme name
71
+ --custom-theme-template <char> custom theme template; (options: base,
72
+ polaris-flex, polaris-sidebar)
73
+ -V, --version output the version number
74
+ --title <char> Title
75
+ --content <char> Page content
76
+ --slug <char> Path (slug)
77
+ --published <char> Publishing status
78
+ --tags <char> Tags
79
+ --parent <char> Parent
80
+ --order <char> Order
81
+ --theme <char> Theme
82
+ --hide-in-menu <char> Hide in menu
83
+ -h, --help display help for command
57
84
 
58
85
  Commands:
59
- start Interactive program to pick options
60
- site [options] [action]
61
- webcomponent [options] [name] Create Lit based web components, with HAX
62
- recommendations
63
- help [command] display help for command
86
+ start Select which hax sub-program to run
87
+ site [options] [action] create or administer a HAXsite
88
+ webcomponent [options] [name] Create Lit based web components, with HAX
89
+ recommendations
90
+ audit [options] Audits web components for compliance with DDD
91
+ (HAX Design System)
92
+ help [command] display help for command
64
93
  ```
65
-
94
+ ## Examples
95
+ For a detailed list of example commands that you can perform with `hax` see [examples](examples.md).
66
96
  ## Manual
67
97
 
68
98
  ### Linux / macOS
69
99
 
70
100
  Run `man hax` to get detailed manual.
71
101
 
72
- ## Site context
73
- - listing stats
74
- - launch site
75
- - publish to surge.sh (if installed)
76
-
77
- ## Web component context
78
- - launch element
79
-
80
102
  # Alternative Usage
81
103
 
82
104
  ```bash
@@ -128,9 +150,57 @@ Build a HAX site that can be published and transported anywhere. Your users migh
128
150
  - Theme development starting point to be able to build themes locally
129
151
  - Primed to publish to gh-pages, vercel and more
130
152
 
153
+ ## HAX Audit
154
+ Audits your HAX based web components to suggest improvements to better align with DDD, the design system built into HAX components.
155
+ - Use `.dddignore` file to instruct audit program what files should be ignored. Each component generated comes with a `.dddignore` file in its root directory.
156
+ - Run command from root of the component project.
157
+ - Provides suggested changes for component CSS to align with DDD design standards, if a change cannot be suggested, developer will be refered to look at the manual for a change that works for them!
158
+
159
+ ### `.dddignore` Template
160
+
161
+ ```gitignore
162
+ # Directories
163
+ # (Must start with with / or \, as seen below)
164
+ /.github # Inline comments are supported
165
+ /.vscode
166
+ /.idea
167
+ /locales
168
+ \test
169
+ /dist
170
+ /build
171
+ /public # ignored by program regardless of presence in .dddignore
172
+ /node_modules # ignored by program regardless of presence in .dddignore
173
+
174
+ # Files
175
+ # (Must include filename and extension, as seen below)
176
+ LICENSE
177
+ .dddignore
178
+ .editorconfig
179
+ .gitignore
180
+ .nojekyll
181
+ .npmignore
182
+ .surgeignore
183
+ rollup.config.js
184
+
185
+ # File extension
186
+ # (Must start with *, as seen below)
187
+ *.md
188
+ *.yml
189
+ *.json
190
+ *.toml
191
+ *.mjs
192
+ *.cjs
193
+ *.png
194
+ *.ico
195
+ *.svg
196
+ *.jpg
197
+ *.jpeg
198
+ ```
199
+
131
200
  # Get Help / Issues / Support
132
201
  - Discord Channel - https://bit.ly/hax-discord
133
202
  - Unified issue queue - https://github.com/haxtheweb/issues/issues
203
+ - DDD Documentation - https://haxtheweb.org/documentation/ddd
134
204
  - Using Merlin directly in any HAX spaces and type "Issue" to jump start a report!
135
205
 
136
206
  ## Watch and Learn more about HAX here:
package/dist/create.js CHANGED
@@ -8,6 +8,7 @@ var p = _interopRequireWildcard(require("@clack/prompts"));
8
8
  var _picocolors = _interopRequireDefault(require("picocolors"));
9
9
  var _statements = require("./lib/statements.js");
10
10
  var _logging = require("./lib/logging.js");
11
+ var _audit = require("./lib/programs/audit.js");
11
12
  var _webcomponent = require("./lib/programs/webcomponent.js");
12
13
  var _site = require("./lib/programs/site.js");
13
14
  var _utils = require("./lib/utils.js");
@@ -28,14 +29,23 @@ exec('git --version', error => {
28
29
  }
29
30
  });
30
31
  async function main() {
32
+ let wcReg = {};
33
+ let regPath = path.join(__dirname, './lib/wc-registry.json');
34
+ if (fs.existsSync(regPath)) {
35
+ try {
36
+ wcReg = JSON.parse(fs.readFileSync(regPath));
37
+ } catch (e) {
38
+ // no registry for testing, probably busted package
39
+ }
40
+ }
31
41
  var commandRun = {};
32
- _commander.program.option('--').option('--v', 'Verbose output').option('--debug', 'Output for developers').option('--format <char>', 'Output format; json (default), yaml').option('--path <char>', 'where to perform operation').option('--npm-client <char>', 'npm client to use (must be installed) npm, yarn, pnpm', 'npm').option('--y', 'yes to all questions').option('--skip', 'skip frills like animations').option('--quiet', 'remove console logging').option('--auto', 'yes to all questions, alias of y').option('--no-i', 'prevent interactions / sub-process, good for scripting').option('--to-file <char>', 'redirect command output to a file').option('--no-extras', 'skip all extra / automatic command processing').option('--root <char>', 'root location to execute the command from')
42
+ _commander.program.option('--').option('--v', 'Verbose output').option('--debug', 'Output for developers').option('--format <char>', 'Output format; json (default), yaml').option('--path <char>', 'where to perform operation').option('--name <char>', 'name of the project/web component').option('--npm-client <char>', 'npm client to use (must be installed) npm, yarn, pnpm', 'npm').option('--y', 'yes to all questions').option('--skip', 'skip frills like animations').option('--quiet', 'remove console logging').option('--auto', 'yes to all questions, alias of y').option('--no-i', 'prevent interactions / sub-process, good for scripting').option('--to-file <char>', 'redirect command output to a file').option('--no-extras', 'skip all extra / automatic command processing').option('--root <char>', 'root location to execute the command from')
33
43
 
34
44
  // options for webcomponent
35
45
  .option('--org <char>', 'organization for package.json').option('--author <char>', 'author for site / package.json').option('--writeHaxProperties', 'Write haxProperties for the element')
36
46
 
37
47
  // options for site
38
- .option('--import-site <char>', 'URL of site to import').option('--import-structure <char>', `import method to use:\n\rpressbooksToSite\n\relmslnToSite\n\rhaxcmsToSite\n\rnotionToSite\n\rgitbookToSite\n\revolutionToSite\n\rhtmlToSite\n\rdocxToSite`).option('--node-op <char>', 'node operation to perform').option('--item-id <char>', 'node ID to operate on').option('--name <char>', 'name of the project').option('--domain <char>', 'published domain name').option('--title-scrape <char>', 'CSS Selector for `title` in resource').option('--content-scrape <char>', 'CSS Selector for `body` in resource').option('--items-import <char>', 'import items from a file / site').option('--recipe <char>', 'path to recipe file').option('--custom-theme-name <char>', 'custom theme name').option('--custom-theme-template <char>', 'custom theme template; (options: base, polaris-flex, polaris-sidebar)').version(await HAXCMS.getHAXCMSVersion()).helpCommand(true);
48
+ .option('--import-site <char>', 'URL of site to import').option('--import-structure <char>', `import method to use:\n\rpressbooksToSite\n\relmslnToSite\n\rhaxcmsToSite\n\rnotionToSite\n\rgitbookToSite\n\revolutionToSite\n\rhtmlToSite\n\rdocxToSite`).option('--node-op <char>', 'node operation to perform').option('--item-id <char>', 'node ID to operate on').option('--domain <char>', 'published domain name').option('--title-scrape <char>', 'CSS Selector for `title` in resource').option('--content-scrape <char>', 'CSS Selector for `body` in resource').option('--items-import <char>', 'import items from a file / site').option('--recipe <char>', 'path to recipe file').option('--custom-theme-name <char>', 'custom theme name').option('--custom-theme-template <char>', 'custom theme template; (options: base, polaris-flex, polaris-sidebar)').version(await HAXCMS.getHAXCMSVersion()).helpCommand(true);
39
49
 
40
50
  // default command which runs interactively
41
51
  _commander.program.command('start').description('Select which hax sub-program to run').action(() => {
@@ -61,25 +71,40 @@ async function main() {
61
71
  commandRun.arguments.action = action;
62
72
  commandRun.options.skip = true;
63
73
  }
64
- }).option('--v', 'Verbose output').option('--debug', 'Output for developers').option('--format <char>', 'Output format; json (default), yaml').option('--path <char>', 'where to perform operation').option('--npm-client <char>', 'npm client to use (must be installed) npm, yarn, pnpm', 'npm').option('--y', 'yes to all questions').option('--skip', 'skip frills like animations').option('--quiet', 'remove console logging').option('--auto', 'yes to all questions, alias of y').option('--no-i', 'prevent interactions / sub-process, good for scripting').option('--to-file <char>', 'redirect command output to a file').option('--no-extras', 'skip all extra / automatic command processing').option('--root <char>', 'root location to execute the command from').option('--import-site <char>', 'URL of site to import').option('--import-structure <char>', `import method to use:\n\rpressbooksToSite\n\relmslnToSite\n\rhaxcmsToSite\n\rnotionToSite\n\rgitbookToSite\n\revolutionToSite\n\rhtmlToSite\n\rdocxToSite`).option('--name <char>', 'name of the site (when creating a new one)').option('--domain <char>', 'published domain name').option('--node-op <char>', 'node operation to perform').option('--title-scrape <char>', 'CSS Selector for `title` in resource').option('--content-scrape <char>', 'CSS Selector for `body` in resource').option('--item-import <char>', 'import items from a file / site').option('--recipe <char>', 'path to recipe file').option('--custom-theme-name <char>', 'custom theme name').option('--custom-theme-template <char>', 'custom theme template (options: base, polaris-flex, polaris-sidebar)').version(await HAXCMS.getHAXCMSVersion());
74
+ }).option('--v', 'Verbose output').option('--debug', 'Output for developers').option('--format <char>', 'Output format; json (default), yaml').option('--path <char>', 'where to perform operation').option('--npm-client <char>', 'npm client to use (must be installed) npm, yarn, pnpm', 'npm').option('--y', 'yes to all questions').option('--skip', 'skip frills like animations').option('--quiet', 'remove console logging').option('--auto', 'yes to all questions, alias of y').option('--no-i', 'prevent interactions / sub-process, good for scripting').option('--to-file <char>', 'redirect command output to a file').option('--no-extras', 'skip all extra / automatic command processing').option('--root <char>', 'root location to execute the command from').option('--import-site <char>', 'URL of site to import').option('--import-structure <char>', `import method to use:\n\rpressbooksToSite\n\relmslnToSite\n\rhaxcmsToSite\n\rnotionToSite\n\rgitbookToSite\n\revolutionToSite\n\rhtmlToSite\n\rdocxToSite`).option('--name <char>', 'name of the site (when creating a new one)').option('--domain <char>', 'published domain name').option('--node-op <char>', 'node operation to perform').option('--title-scrape <char>', 'CSS Selector for `title` in resource').option('--content-scrape <char>', 'CSS Selector for `body` in resource').option('--items-import <char>', 'import items from a file / site').option('--recipe <char>', 'path to recipe file').option('--custom-theme-name <char>', 'custom theme name').option('--custom-theme-template <char>', 'custom theme template (options: base, polaris-flex, polaris-sidebar)').version(await HAXCMS.getHAXCMSVersion());
65
75
  let siteNodeOps = (0, _site.siteNodeOperations)();
66
76
  for (var i in siteNodeOps) {
67
77
  _commander.program.option(`--${(0, _utils.camelToDash)(siteNodeOps[i].value)} <char>`, `${siteNodeOps[i].label}`);
68
78
  siteProg.option(`--${(0, _utils.camelToDash)(siteNodeOps[i].value)} <char>`, `${siteNodeOps[i].label}`);
69
79
  }
80
+
70
81
  // webcomponent program
71
- _commander.program.command('webcomponent').description('Create Lit based web components, with HAX recommendations').argument('[name]', 'name of the project').action(name => {
82
+ let strWebcomponentActions = '';
83
+ (0, _webcomponent.webcomponentActions)().forEach(action => {
84
+ strWebcomponentActions += `${action.value} - ${action.label}` + "\n\r";
85
+ });
86
+ _commander.program.command('wc').alias('webcomponent').description('Create Lit based web components, with HAX recommendations').argument('[action]', 'Actions to perform on web component include:' + "\n\r" + strWebcomponentActions).action(action => {
72
87
  commandRun = {
73
88
  command: 'webcomponent',
74
89
  arguments: {},
75
90
  options: {}
76
91
  };
77
92
  // if name set, populate
78
- if (name) {
79
- commandRun.arguments.name = name;
93
+ if (action) {
94
+ commandRun.arguments.action = action;
80
95
  commandRun.options.skip = true;
81
96
  }
82
- }).option('--path <char>', 'path the project should be created in').option('--org <char>', 'organization for package.json').option('--author <char>', 'author for site / package.json').option('--writeHaxProperties', 'Write haxProperties for the element').option('--to-file <char>', 'redirect command output to a file').option('--no-extras', 'skip all extra / automatic command processing').option('--no-i', 'prevent interactions / sub-process, good for scripting').option('--root <char>', 'root location to execute the command from').version(await HAXCMS.getHAXCMSVersion());
97
+ }).option('--path <char>', 'path the project should be created in').option('--org <char>', 'organization for package.json').option('--author <char>', 'author for site / package.json').option('--name <char>', 'name of the web component').option('--writeHaxProperties', 'Write haxProperties for the element').option('--to-file <char>', 'redirect command output to a file').option('--no-extras', 'skip all extra / automatic command processing').option('--no-i', 'prevent interactions / sub-process, good for scripting').option('--root <char>', 'root location to execute the command from').version(await HAXCMS.getHAXCMSVersion());
98
+
99
+ // audit program
100
+ _commander.program.command('audit').description('Audits web components for compliance with DDD (HAX design system)').action(() => {
101
+ commandRun = {
102
+ command: 'audit',
103
+ arguments: {},
104
+ options: {}
105
+ };
106
+ }).option('--debug', 'Output for developers').version(await HAXCMS.getHAXCMSVersion());
107
+
83
108
  // process program arguments
84
109
  _commander.program.parse();
85
110
  commandRun.options = {
@@ -168,13 +193,17 @@ async function main() {
168
193
  commandRun.options.isMonorepo = true;
169
194
  commandRun.options.auto = true;
170
195
  // assumed if monorepo
171
- commandRun.command = 'webcomponent';
172
- commandRun.options.path = path.join(process.cwd(), packageData.workspaces.packages[0].replace('/*', ''));
173
- if (packageData.orgNpm) {
174
- commandRun.options.org = packageData.orgNpm;
196
+ if (commandRun.command === "audit") {
197
+ (0, _audit.auditCommandDetected)(commandRun);
198
+ } else {
199
+ commandRun.command = 'webcomponent';
200
+ commandRun.options.path = path.join(process.cwd(), packageData.workspaces.packages[0].replace('/*', ''));
201
+ if (packageData.orgNpm) {
202
+ commandRun.options.org = packageData.orgNpm;
203
+ }
204
+ commandRun.options.gitRepo = packageData.repository.url;
205
+ commandRun.options.author = packageData.author.name ? packageData.author.name : author;
175
206
  }
176
- commandRun.options.gitRepo = packageData.repository.url;
177
- commandRun.options.author = packageData.author.name ? packageData.author.name : author;
178
207
  }
179
208
  } catch (err) {
180
209
  console.error(err);
@@ -189,6 +218,8 @@ async function main() {
189
218
  commandRun.program = 'site';
190
219
  commandRun.options.skip = true;
191
220
  await (0, _site.siteCommandDetected)(commandRun);
221
+ } else if (commandRun.command === 'audit') {
222
+ (0, _audit.auditCommandDetected)(commandRun);
192
223
  } else if (packageData && (packageData.customElements || packageData.hax && packageData.hax.cli) && packageData.scripts.start) {
193
224
  commandRun.program = 'webcomponent';
194
225
  commandRun.options.skip = true;
@@ -220,7 +251,7 @@ async function main() {
220
251
  options: {}
221
252
  };
222
253
  }
223
- if (['site', 'webcomponent'].includes(commandRun.command)) {
254
+ if (['site', 'webcomponent', 'audit'].includes(commandRun.command)) {
224
255
  project = {
225
256
  type: commandRun.command
226
257
  };
@@ -266,14 +297,8 @@ async function main() {
266
297
  activeProject = project.type;
267
298
  // silly but this way we don't have to take options for quitting
268
299
  if (project.type !== 'quit') {
269
- // also silly temp spot
270
- let themes = await (0, _site.siteThemeList)();
271
- const custom = {
272
- value: 'custom-theme',
273
- label: 'Create Custom Theme'
274
- };
275
- // Append custom option to list of core themes
276
- themes.push(custom);
300
+ // global spot for core themes list
301
+ let coreThemes = await (0, _site.siteThemeList)(true);
277
302
  project = await p.group({
278
303
  type: ({
279
304
  results
@@ -305,7 +330,7 @@ async function main() {
305
330
  name: ({
306
331
  results
307
332
  }) => {
308
- if (!commandRun.arguments.action && !commandRun.arguments.name) {
333
+ if (!commandRun.arguments.action) {
309
334
  let placeholder = "mysite";
310
335
  let message = "Site name:";
311
336
  if (commandRun.command === "webcomponent" || results.type === "webcomponent") {
@@ -320,15 +345,22 @@ async function main() {
320
345
  if (!value) {
321
346
  return "Name is required (tab writes default)";
322
347
  }
348
+ if (value.toLocaleLowerCase() !== value) {
349
+ return "Name must be lowercase";
350
+ }
323
351
  if (/^\d/.test(value)) {
324
352
  return "Name cannot start with a number";
325
353
  }
326
354
  if (value.indexOf(' ') !== -1) {
327
- return "No spaces allowed in project name";
355
+ return "No spaces allowed in name";
328
356
  }
329
- if (results.type === "webcomponent" && value.indexOf('-') === -1 && value.indexOf('-') !== 0 && value.indexOf('-') !== value.length - 1) {
357
+ if (results.type === "webcomponent" && (value.indexOf('-') === -1 || value.replace('--', '') !== value || value[0] === '-' || value[value.length - 1] === '-')) {
330
358
  return "Name must include at least one `-` and must not start or end name.";
331
359
  }
360
+ // test that this is not an existing element we use in the registry
361
+ if (results.type === "webcomponent" && wcReg[value]) {
362
+ return "Name is already a web component in the wc-registry published for HAX.";
363
+ }
332
364
  // assumes auto was selected in CLI
333
365
  let joint = process.cwd();
334
366
  if (commandRun.options.path) {
@@ -342,6 +374,44 @@ async function main() {
342
374
  }
343
375
  });
344
376
  }
377
+ if (commandRun.arguments.action) {
378
+ let value = commandRun.arguments.action;
379
+ if (!value) {
380
+ _commander.program.error(_picocolors.default.red("Name is required (tab writes default)"));
381
+ process.exit(1);
382
+ }
383
+ if (value.toLocaleLowerCase() !== value) {
384
+ _commander.program.error(_picocolors.default.red("Name must be lowercase"));
385
+ process.exit(1);
386
+ }
387
+ if (/^\d/.test(value)) {
388
+ _commander.program.error(_picocolors.default.red("Name cannot start with a number"));
389
+ }
390
+ if (value.indexOf(' ') !== -1) {
391
+ _commander.program.error(_picocolors.default.red("No spaces allowed in name"));
392
+ process.exit(1);
393
+ }
394
+ if (results.type === "webcomponent" && (value.indexOf('-') === -1 || value.replace('--', '') !== value || value[0] === '-' || value[value.length - 1] === '-')) {
395
+ _commander.program.error(_picocolors.default.red("Name must include at least one `-` and must not start or end name."));
396
+ process.exit(1);
397
+ }
398
+ // test that this is not an existing element we use in the registry
399
+ if (results.type === "webcomponent" && wcReg[value]) {
400
+ _commander.program.error(_picocolors.default.red("Name is already a web component in the wc-registry published for HAX."));
401
+ process.exit(1);
402
+ }
403
+ // assumes auto was selected in CLI
404
+ let joint = process.cwd();
405
+ if (commandRun.options.path) {
406
+ joint = commandRun.options.path;
407
+ } else if (results.path) {
408
+ joint = results.path;
409
+ }
410
+ if (fs.existsSync(path.join(joint, value))) {
411
+ _commander.program.error(_picocolors.default.red(`${path.join(joint, value)} exists, rename this project`));
412
+ process.exit(1);
413
+ }
414
+ }
345
415
  },
346
416
  org: ({
347
417
  results
@@ -377,15 +447,20 @@ async function main() {
377
447
  if (results.type === "site" && !commandRun.options.theme) {
378
448
  // support having no theme but autoselecting
379
449
  if (commandRun.options.auto && commandRun.options.skip) {
380
- commandRun.options.theme = themes[0].value;
450
+ commandRun.options.theme = coreThemes[0].value;
381
451
  } else {
382
452
  return p.select({
383
453
  message: "Theme:",
384
454
  required: false,
385
- options: themes,
386
- initialValue: themes[0]
455
+ options: coreThemes,
456
+ initialValue: coreThemes[0]
387
457
  });
388
458
  }
459
+ } else if (results.type === "site" && commandRun.options.theme) {
460
+ if (coreThemes.filter(item => item.value === commandRun.options.theme).length === 0) {
461
+ _commander.program.error(_picocolors.default.red('Theme is not in the list of valid themes'));
462
+ process.exit(1);
463
+ }
389
464
  }
390
465
  },
391
466
  customThemeName: async ({
@@ -394,13 +469,13 @@ async function main() {
394
469
  if (results.theme === "custom-theme") {
395
470
  let tmpCustomName = await p.text({
396
471
  message: 'Theme Name:',
397
- placeholder: `${results.name}`,
472
+ placeholder: `custom-${commandRun.arguments.action ? commandRun.arguments.action : results.name}-theme`,
398
473
  required: false,
399
474
  validate: value => {
400
475
  if (!value) {
401
476
  return "Theme name is required (tab writes default)";
402
477
  }
403
- if (themes.some(theme => theme.value === value)) {
478
+ if (coreThemes.some(theme => theme.value === value)) {
404
479
  return "Theme name is already in use";
405
480
  }
406
481
  if (/^\d/.test(value)) {
@@ -415,6 +490,24 @@ async function main() {
415
490
  }
416
491
  });
417
492
  return tmpCustomName;
493
+ } else if (results.type === "site") {
494
+ // need to validate theme from CLI arguments
495
+ let value = `${commandRun.options.customThemeName ? commandRun.options.customThemeName : results.name ? results.name : commandRun.arguments.action}`;
496
+ if (!value) {
497
+ _commander.program.error(_picocolors.default.red("Theme name is required (tab writes default)"));
498
+ }
499
+ if (coreThemes.some(theme => theme.value === value)) {
500
+ _commander.program.error(_picocolors.default.red("Theme name is already in use"));
501
+ }
502
+ if (/^\d/.test(value)) {
503
+ _commander.program.error(_picocolors.default.red("Theme name cannot start with a number"));
504
+ }
505
+ if (/[A-Z]/.test(value)) {
506
+ _commander.program.error(_picocolors.default.red("No uppercase letters allowed in theme name"));
507
+ }
508
+ if (value.indexOf(' ') !== -1) {
509
+ _commander.program.error(_picocolors.default.red("No spaces allowed in theme name"));
510
+ }
418
511
  }
419
512
  },
420
513
  customThemeTemplate: ({
@@ -491,7 +584,7 @@ async function main() {
491
584
  });
492
585
  // merge cli options with project options assume this is NOT a monorepo
493
586
  // but spread will overwrite if needed
494
- if (commandRun.command === 'webcomponent' && !commandRun.arguments.name) {
587
+ if (commandRun.command === 'webcomponent' && !commandRun.arguments.action) {
495
588
  project = {
496
589
  isMonorepo: false,
497
590
  ...project,
@@ -507,16 +600,22 @@ async function main() {
507
600
  }
508
601
  project.year = new Date().getFullYear();
509
602
  project.version = await HAXCMS.getHAXCMSVersion();
603
+ if (!project.name && commandRun.arguments.action) {
604
+ project.name = commandRun.arguments.action;
605
+ }
606
+
510
607
  // resolve site vs multi-site
511
608
  switch (project.type) {
512
609
  case 'site':
513
- if (!project.name && commandRun.arguments.action) {
514
- project.name = commandRun.arguments.action;
610
+ // only set path if not already set, normalize across clack and commander
611
+ if (commandRun.options.path && !project.path) {
612
+ project.path = commandRun.options.path;
613
+ }
614
+ if (!project.path) {
615
+ project.path = process.cwd();
515
616
  }
516
- // only set path if not already set
517
617
  if (!commandRun.options.path) {
518
- commandRun.options.path = process.cwd();
519
- project.path = commandRun.options.path;
618
+ commandRun.options.path = project.path;
520
619
  }
521
620
  await (0, _site.siteProcess)(commandRun, project);
522
621
  break;
package/dist/docs/hax.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH HAX\-CREATE 1 hax 9.0.18 "HAX COMMAND INTERFACE MANUAL"
1
+ .TH HAX\-CREATE 1 hax hax "HAX COMMAND INTERFACE MANUAL"
2
2
 
3
3
  .SH NAME
4
4
  hax \- a tool to create HAX websites and web components quickly.
@@ -22,6 +22,9 @@ This command line tool can be used to create and modify two different HAX based
22
22
  .B webcomponent
23
23
  [options] [name] \- Create Lit based web components, with HAX recommendations
24
24
  .PP
25
+ .B audit
26
+ [options] \- Audits web components for compliance with DDD (HAX design system)
27
+ .PP
25
28
  .B help
26
29
  [command] \- Display help for command
27
30
 
@@ -57,6 +60,12 @@ Prevent interactions / sub\-process, good for scripting
57
60
  \--to\-file [char]
58
61
  Redirect command output to a file
59
62
  .TP
63
+ \--no\-extras
64
+ Skip all extra / automatic commmand processing
65
+ .TP
66
+ \--root [location]
67
+ Root location to execute the command from
68
+ .TP
60
69
  \--org [organization]
61
70
  Organization for package.json
62
71
  .TP
@@ -84,9 +93,27 @@ Name of the project
84
93
  \--domain [name]
85
94
  Published domain name
86
95
  .TP
96
+ \--title\-scrape [selector]
97
+ CSS selector for `title` in resource
98
+ .TP
99
+ \--content\-scrape [selector[
100
+ CSS selector for `body` in resource
101
+ .TP
87
102
  \--items\-import [char]
88
103
  Import items from a file / site
89
104
  .TP
105
+ \--recipe [path]
106
+ Path to recipe file
107
+ .TP
108
+ \--custom\-theme\-name [name]
109
+ Custom theme name
110
+ .TP
111
+ \--custom\-theme\-template [option]
112
+ Custom theme template (Options: base | polaris-flex | polaris-sidebar)
113
+ .TP
114
+ \-V, \--version
115
+ Output the version number
116
+ .TP
90
117
  \--title [title]
91
118
  Title
92
119
  .TP
@@ -122,11 +149,14 @@ Display help for command
122
149
  .B hax start
123
150
  Navigatable interface
124
151
  .TP
152
+ .B hax site mysite --y
153
+ Create a new HAXsite (HAXcms, single site)
154
+ .TP
125
155
  .B hax webcomponent my-element --y
126
156
  Make a new HAX capable, i18n wired, design system (DDD) driven web component
127
157
  .TP
128
- .B hax site mysite --y
129
- Create a new HAXsite (HAXcms, single site)
158
+ .B hax audit
159
+ Audit web components for compliance with DDD (HAX design system)
130
160
 
131
161
  .SH BUGS
132
162
  Bugs can be viewed at GitHub Issues: https://github.com/haxtheweb/issues/issues
@@ -143,6 +173,10 @@ https://github.com/haxtheweb/create
143
173
  .PP
144
174
  .B Web Components Repository:
145
175
  https://github.com/haxtheweb/webcomponents
176
+ .PP
177
+ .B DDD Design System Documentation
178
+ https://haxtheweb.org/documentation/ddd
179
+
146
180
 
147
181
  .SH AUTHORS
148
182
  .PP
@@ -8,7 +8,7 @@ exports.enableCoreServices = enableCoreServices;
8
8
  exports.enableExperimentalServices = enableExperimentalServices;
9
9
  exports.enableHAXcmsServices = enableHAXcmsServices;
10
10
  exports.enableServices = enableServices;
11
- var _statements = require("./statements.js");
11
+ var _logging = require("./logging.js");
12
12
  // because node hates mixing modern web at times this is a fork of @haxtheweb/micro-frontend-registry
13
13
  // and can fall out of date
14
14
  /**
@@ -51,8 +51,8 @@ const MicroFrontendRegCapabilities = function (SuperClass) {
51
51
  */
52
52
  define(item) {
53
53
  if (!(item instanceof MicroFrontend)) {
54
- (0, _statements.log)("MicroFrontendRegistry: use class MicroFrontend instance but if keys match it will register still.", 'warn');
55
- (0, _statements.log)(item, 'warn');
54
+ (0, _logging.log)("MicroFrontendRegistry: use class MicroFrontend instance but if keys match it will register still.", 'warn');
55
+ (0, _logging.log)(item, 'warn');
56
56
  }
57
57
  // validate item has all keys we care about
58
58
  if (Object.keys(item).every(key => MicroFrontendKeys.includes(key))) {
@@ -103,7 +103,7 @@ const MicroFrontendRegCapabilities = function (SuperClass) {
103
103
  }
104
104
  }
105
105
  if (!testOnly) {
106
- (0, _statements.log)(`call for ${name} but not found in micro-frontend-registry`, 'error');
106
+ (0, _logging.log)(`call for ${name} but not found in micro-frontend-registry`, 'error');
107
107
  }
108
108
  return null;
109
109
  }
@@ -171,7 +171,7 @@ const MicroFrontendRegCapabilities = function (SuperClass) {
171
171
  data: null
172
172
  };
173
173
  }).catch((e, d) => {
174
- (0, _statements.log)("Request failed", 'warn');
174
+ (0, _logging.log)("Request failed", 'warn');
175
175
  // this is endpoint completely failed to respond
176
176
  return {
177
177
  status: 500,
@@ -191,7 +191,7 @@ const MicroFrontendRegCapabilities = function (SuperClass) {
191
191
  data: null
192
192
  };
193
193
  }).catch((e, d) => {
194
- (0, _statements.log)("Request failed", 'warn');
194
+ (0, _logging.log)("Request failed", 'warn');
195
195
  // this is endpoint completely failed to respond
196
196
  return {
197
197
  status: 500,