@haxtheweb/create 9.0.22 → 9.0.24

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/dist/create.js CHANGED
@@ -7,6 +7,7 @@ var path = _interopRequireWildcard(require("node:path"));
7
7
  var p = _interopRequireWildcard(require("@clack/prompts"));
8
8
  var _picocolors = _interopRequireDefault(require("picocolors"));
9
9
  var _statements = require("./lib/statements.js");
10
+ var _logging = require("./lib/logging.js");
10
11
  var _webcomponent = require("./lib/programs/webcomponent.js");
11
12
  var _site = require("./lib/programs/site.js");
12
13
  var _utils = require("./lib/utils.js");
@@ -28,16 +29,16 @@ exec('git --version', error => {
28
29
  });
29
30
  async function main() {
30
31
  var commandRun = {};
31
- _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')
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')
32
33
 
33
34
  // options for webcomponent
34
35
  .option('--org <char>', 'organization for package.json').option('--author <char>', 'author for site / package.json').option('--writeHaxProperties', 'Write haxProperties for the element')
35
36
 
36
37
  // options for site
37
- .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').version(await HAXCMS.getHAXCMSVersion()).helpCommand(true);
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').version(await HAXCMS.getHAXCMSVersion()).helpCommand(true);
38
39
 
39
40
  // default command which runs interactively
40
- _commander.program.command('start').description('Interactive program to pick options').action(() => {
41
+ _commander.program.command('start').description('Select which hax sub-program to run').action(() => {
41
42
  commandRun = {
42
43
  command: 'start',
43
44
  arguments: {},
@@ -50,8 +51,7 @@ async function main() {
50
51
  (0, _site.siteActions)().forEach(action => {
51
52
  strActions += `${action.value} - ${action.label}` + "\n\r";
52
53
  });
53
- let siteProg = _commander.program.command('site');
54
- siteProg.argument('[action]', 'Actions to perform on site include:' + "\n\r" + strActions).action(action => {
54
+ let siteProg = _commander.program.command('site').description('create or administer a HAXsite').argument('[action]', 'Actions to perform on site include:' + "\n\r" + strActions).action(action => {
55
55
  commandRun = {
56
56
  command: 'site',
57
57
  arguments: {},
@@ -61,13 +61,12 @@ async function main() {
61
61
  commandRun.arguments.action = action;
62
62
  commandRun.options.skip = true;
63
63
  }
64
- }).option('--path <char>', 'path the project should be created in').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('--no-i', 'prevent interactions / sub-process, good for scripting').option('--title-scrape <char>', 'CSS Selector for `title` in resource').option('--content-scrape <char>', 'CSS Selector for `body` in resource').option('--to-file <char>', 'redirect command output to a file').option('--no-extras', 'skip all extra / automatic command processing').option('--item-import <char>', 'import items from a file / site').version(await HAXCMS.getHAXCMSVersion());
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').version(await HAXCMS.getHAXCMSVersion());
65
65
  let siteNodeOps = (0, _site.siteNodeOperations)();
66
66
  for (var i in siteNodeOps) {
67
67
  _commander.program.option(`--${(0, _utils.camelToDash)(siteNodeOps[i].value)} <char>`, `${siteNodeOps[i].label}`);
68
68
  siteProg.option(`--${(0, _utils.camelToDash)(siteNodeOps[i].value)} <char>`, `${siteNodeOps[i].label}`);
69
69
  }
70
-
71
70
  // webcomponent program
72
71
  _commander.program.command('webcomponent').description('Create Lit based web components, with HAX recommendations').argument('[name]', 'name of the project').action(name => {
73
72
  commandRun = {
@@ -80,15 +79,32 @@ async function main() {
80
79
  commandRun.arguments.name = name;
81
80
  commandRun.options.skip = true;
82
81
  }
83
- }).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').version(await HAXCMS.getHAXCMSVersion());
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());
84
83
  // process program arguments
85
84
  _commander.program.parse();
86
85
  commandRun.options = {
87
86
  ...commandRun.options,
88
87
  ..._commander.program.opts()
89
88
  };
89
+ // this is a false positive bc of the no-extras flag. no-extras does not imply true if not there
90
+ // but that's how the CLI works. This then bombs things downstream. Its good to be false but NOT
91
+ // good to be true since we need an array of options
92
+ if (commandRun.options.extras === true) {
93
+ delete commandRun.options.extras;
94
+ }
95
+ // allow execution of the command from a different location
96
+ if (commandRun.options.root) {
97
+ process.chdir(commandRun.options.root);
98
+ }
99
+ // bridge to log so we can respect this setting
100
+ if (commandRun.options.quiet) {
101
+ process.haxquiet = true;
102
+ // don't output to the console any messages on this run since told to be silent
103
+ // logging still happens to log files
104
+ _logging.logger.remove(_logging.consoleTransport);
105
+ }
90
106
  if (commandRun.options.debug) {
91
- (0, _statements.log)(commandRun);
107
+ (0, _logging.log)(commandRun, 'debug');
92
108
  }
93
109
  // auto and y assume same thing
94
110
  if (commandRun.options.y || commandRun.options.auto) {
@@ -101,15 +117,11 @@ async function main() {
101
117
  let value = await exec(`git config user.name`);
102
118
  author = value.stdout.trim();
103
119
  } catch (e) {
104
- (0, _statements.log)('git user name not configured. Run the following to do this:');
105
- (0, _statements.log)('git config --global user.name "namehere"');
106
- (0, _statements.log)('git config --global user.email "email@here');
107
- }
108
- // bridge to log so we can respect this setting
109
- if (commandRun.options.quiet) {
110
- process.haxquiet = true;
120
+ (0, _logging.log)(`
121
+ git user name not configured. Run the following to do this:\n
122
+ git config --global user.name "namehere"\n
123
+ git config --global user.email "email@here`, 'debug');
111
124
  }
112
- // only set path if not already set
113
125
  if (!commandRun.options.path && commandRun.options.skip) {
114
126
  commandRun.options.path = process.cwd();
115
127
  }
@@ -166,7 +178,7 @@ async function main() {
166
178
  }
167
179
  }
168
180
  if (commandRun.options.debug) {
169
- (0, _statements.log)(packageData);
181
+ (0, _logging.log)(packageData, 'debug');
170
182
  }
171
183
  // CLI works within context of the site if one is detected, otherwise we can do other thingss
172
184
  if (await hax.systemStructureContext()) {
@@ -354,7 +366,7 @@ async function main() {
354
366
  if (results.type === "site" && !commandRun.options.theme) {
355
367
  // support having no theme but autoselecting
356
368
  if (commandRun.options.auto && commandRun.options.skip) {
357
- commandRun.options.theme = themes[0];
369
+ commandRun.options.theme = themes[0].value;
358
370
  } else {
359
371
  return p.select({
360
372
  message: "Theme:",
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.commandString = commandString;
7
+ exports.consoleTransport = void 0;
8
+ exports.haxCliEnvOptions = haxCliEnvOptions;
9
+ exports.log = log;
10
+ exports.logger = exports.logFile = void 0;
11
+ var _nodeOs = require("node:os");
12
+ var path = _interopRequireWildcard(require("node:path"));
13
+ var winston = _interopRequireWildcard(require("winston"));
14
+ var _utils = require("./utils.js");
15
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
16
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
+ const logFileName = path.join((0, _nodeOs.homedir)(), '.haxtheweb', 'create.log');
18
+ const consoleTransport = exports.consoleTransport = new winston.transports.Console({
19
+ format: winston.format.simple()
20
+ });
21
+ const logFile = exports.logFile = new winston.transports.File({
22
+ filename: logFileName,
23
+ level: 'info',
24
+ // so we don't store everything else
25
+ format: winston.format.combine(winston.format.timestamp({
26
+ format: 'YYYY-MM-DD HH:mm:ss'
27
+ }), winston.format.errors({
28
+ stack: true
29
+ }), winston.format.splat(), winston.format.json()),
30
+ maxsize: 100000,
31
+ maxFiles: 10,
32
+ tailable: true
33
+ });
34
+ const logger = exports.logger = winston.createLogger({
35
+ transports: [consoleTransport, logFile]
36
+ });
37
+ function haxCliEnvOptions() {
38
+ return ['skip', 'npmClient', 'i', 'extras', 'root', 'path', 'org', 'author', 'y', 'auto'];
39
+ }
40
+
41
+ // wrapper so we can silence all log messages at the same time
42
+ function log(msg, level = 'info', extra = null) {
43
+ logger.log(level, msg, extra);
44
+ }
45
+ function commandString(commandRun) {
46
+ let comStr = `hax ${commandRun.command} ${commandRun.arguments.action}`;
47
+ for (const key of Object.keys(commandRun.options)) {
48
+ // ignore environment centric calls
49
+ if (!haxCliEnvOptions().includes(key)) {
50
+ if (key === true) {
51
+ comStr += ` --${(0, _utils.camelToDash)(key)}`;
52
+ } else if (key === false) {
53
+ comStr += ` --no-${(0, _utils.camelToDash)(key)}`;
54
+ } else {
55
+ comStr += ` --${(0, _utils.camelToDash)(key)} "${commandRun.options[key]}"`;
56
+ }
57
+ }
58
+ }
59
+ return comStr;
60
+ }
@@ -13,11 +13,14 @@ exports.siteProcess = siteProcess;
13
13
  exports.siteThemeList = siteThemeList;
14
14
  var _promises = require("node:timers/promises");
15
15
  var fs = _interopRequireWildcard(require("node:fs"));
16
+ var path = _interopRequireWildcard(require("node:path"));
16
17
  var p = _interopRequireWildcard(require("@clack/prompts"));
17
18
  var _picocolors = _interopRequireDefault(require("picocolors"));
18
19
  var _jsYaml = require("js-yaml");
20
+ var winston = _interopRequireWildcard(require("winston"));
19
21
  var _nodeHtmlParser = require("node-html-parser");
20
22
  var _statements = require("../statements.js");
23
+ var _logging = require("../logging.js");
21
24
  var _microFrontendRegistry = require("../micro-frontend-registry.js");
22
25
  var haxcmsNodejsCli = _interopRequireWildcard(require("@haxtheweb/haxcms-nodejs/dist/cli.js"));
23
26
  var hax = _interopRequireWildcard(require("@haxtheweb/haxcms-nodejs"));
@@ -42,6 +45,10 @@ exec('surge --version', error => {
42
45
  sysSurge = false;
43
46
  }
44
47
  });
48
+ const siteRecipeFile = 'create-cli.recipe';
49
+ const siteLoggingName = 'cli';
50
+ const logLevels = {};
51
+ logLevels[siteLoggingName] = 0;
45
52
 
46
53
  // fake response class so we can capture the response from the headless route as opposed to print to console
47
54
  // this way we can handle as data or if use is requesting output format to change we can respond
@@ -113,13 +120,31 @@ function siteActions() {
113
120
  }, {
114
121
  value: 'site:surge',
115
122
  label: "Publish site to Surge.sh"
123
+ }, {
124
+ value: 'recipe:read',
125
+ label: "Read recipe file"
126
+ }, {
127
+ value: 'recipe:play',
128
+ label: "Play recipe file"
116
129
  }];
117
130
  }
118
131
  async function siteCommandDetected(commandRun) {
119
132
  var activeHaxsite = await hax.systemStructureContext();
133
+ const recipeFileName = path.join(process.cwd(), siteRecipeFile);
134
+ const recipeLogTransport = new winston.transports.File({
135
+ filename: recipeFileName
136
+ });
137
+ const recipe = winston.createLogger({
138
+ levels: logLevels,
139
+ level: siteLoggingName,
140
+ transports: [recipeLogTransport],
141
+ format: winston.format.simple()
142
+ });
143
+ let actionAssigned = false;
120
144
  // default to status unless already set so we don't issue a create in a create
121
145
  if (!commandRun.arguments.action) {
122
- commandRun.arguments.action = 'status';
146
+ actionAssigned = true;
147
+ commandRun.arguments.action = 'site:status';
123
148
  }
124
149
  commandRun.command = "site";
125
150
  if (!commandRun.options.y && commandRun.options.i && !commandRun.options.quiet) {
@@ -169,7 +194,11 @@ async function siteCommandDetected(commandRun) {
169
194
  }
170
195
  });
171
196
  }
197
+ if (operation.action) {
198
+ p.intro(`hax site ${_picocolors.default.bold(operation.action)}`);
199
+ }
172
200
  switch (operation.action) {
201
+ case "site:status": // easy mistype
173
202
  case "site:stats":
174
203
  const date = new Date(activeHaxsite.manifest.metadata.site.updated * 1000);
175
204
  let siteItems = [];
@@ -211,9 +240,9 @@ async function siteCommandDetected(commandRun) {
211
240
  p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Last updated: ${siteStats.lastUpdated} `))}`);
212
241
  p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Tags used: ${JSON.stringify(siteStats.tagUsage, null, 2)} `))}`);
213
242
  } else if (commandRun.options.format === 'yaml') {
214
- (0, _statements.log)((0, _jsYaml.dump)(siteStats));
243
+ (0, _logging.log)((0, _jsYaml.dump)(siteStats));
215
244
  } else {
216
- (0, _statements.log)(siteStats);
245
+ (0, _logging.log)(siteStats);
217
246
  }
218
247
  // simple redirecting to file
219
248
  if (commandRun.options.toFile) {
@@ -246,9 +275,9 @@ async function siteCommandDetected(commandRun) {
246
275
  fs.writeFileSync(commandRun.options.toFile, contents);
247
276
  } else {
248
277
  if (commandRun.options.format === 'yaml') {
249
- (0, _statements.log)((0, _jsYaml.dump)(siteitems));
278
+ (0, _logging.log)((0, _jsYaml.dump)(siteitems));
250
279
  } else {
251
- (0, _statements.log)(siteitems);
280
+ (0, _logging.log)(siteitems);
252
281
  }
253
282
  }
254
283
  break;
@@ -313,10 +342,11 @@ async function siteCommandDetected(commandRun) {
313
342
  itemIdMap[josImport.items[i].id] = tmpAddedItem.id;
314
343
  }
315
344
  if (!commandRun.options.quiet) {
316
- (0, _statements.log)(`${josImport.items.length} nodes imported`);
345
+ (0, _logging.log)(`${josImport.items.length} nodes imported`);
317
346
  }
347
+ recipe.log(siteLoggingName, (0, _logging.commandString)(commandRun));
318
348
  } else if (!commandRun.options.quiet) {
319
- (0, _statements.log)('Must specify --item-import as path to valid item export file or URL', 'error');
349
+ (0, _logging.log)('Must specify --item-import as path to valid item export file or URL', 'error');
320
350
  }
321
351
  break;
322
352
  case "start":
@@ -327,9 +357,10 @@ async function siteCommandDetected(commandRun) {
327
357
  }
328
358
  await exec(`cd ${activeHaxsite.directory} && npx @haxtheweb/haxcms-nodejs`);
329
359
  } catch (e) {
330
- (0, _statements.log)(e.stderr);
360
+ (0, _logging.log)(e.stderr);
331
361
  }
332
362
  break;
363
+ case "node:status": // easy mistype
333
364
  case "node:stats":
334
365
  try {
335
366
  if (!commandRun.options.itemId) {
@@ -360,9 +391,9 @@ async function siteCommandDetected(commandRun) {
360
391
  switch (commandRun.options.nodeOp) {
361
392
  case 'details':
362
393
  if (commandRun.options.format === 'yaml') {
363
- (0, _statements.log)((0, _jsYaml.dump)(page));
394
+ (0, _logging.log)((0, _jsYaml.dump)(page));
364
395
  } else {
365
- (0, _statements.log)(page);
396
+ (0, _logging.log)(page);
366
397
  }
367
398
  // simple redirecting to file
368
399
  if (commandRun.options.toFile) {
@@ -379,7 +410,7 @@ async function siteCommandDetected(commandRun) {
379
410
  if (commandRun.options.toFile) {
380
411
  fs.writeFileSync(commandRun.options.toFile, itemHTML);
381
412
  } else {
382
- (0, _statements.log)(itemHTML);
413
+ (0, _logging.log)(itemHTML);
383
414
  }
384
415
  break;
385
416
  case 'schema':
@@ -402,9 +433,9 @@ async function siteCommandDetected(commandRun) {
402
433
  }
403
434
  } else {
404
435
  if (commandRun.options.format === 'yaml') {
405
- (0, _statements.log)((0, _jsYaml.dump)(els));
436
+ (0, _logging.log)((0, _jsYaml.dump)(els));
406
437
  } else {
407
- (0, _statements.log)(els);
438
+ (0, _logging.log)(els);
408
439
  }
409
440
  }
410
441
  break;
@@ -416,15 +447,15 @@ async function siteCommandDetected(commandRun) {
416
447
  if (commandRun.options.toFile) {
417
448
  fs.writeFileSync(commandRun.options.toFile, resp.res.data.data);
418
449
  } else {
419
- (0, _statements.log)(resp.res.data.data);
450
+ (0, _logging.log)(resp.res.data.data);
420
451
  }
421
452
  break;
422
453
  }
423
454
  }
424
455
  }
425
456
  } catch (e) {
426
- (0, _statements.log)(e.stderr);
427
- (0, _statements.log)(e);
457
+ (0, _logging.log)(e.stderr);
458
+ (0, _logging.log)(e);
428
459
  }
429
460
  break;
430
461
  case "node:add":
@@ -495,14 +526,15 @@ async function siteCommandDetected(commandRun) {
495
526
  createNodeBody.node.contents = locationContent;
496
527
  }
497
528
  let resp = await haxcmsNodejsCli.cliBridge('createNode', createNodeBody);
529
+ recipe.log(siteLoggingName, (0, _logging.commandString)(commandRun));
498
530
  if (commandRun.options.v) {
499
- (0, _statements.log)(resp.res.data);
531
+ (0, _logging.log)(resp.res.data, 'silly');
500
532
  }
501
533
  if (!commandRun.options.quiet) {
502
- (0, _statements.log)(`"${createNodeBody.node.title}" added to site`);
534
+ (0, _logging.log)(`"${createNodeBody.node.title}" added to site`, 'info', createNodeBody.node);
503
535
  }
504
536
  } catch (e) {
505
- (0, _statements.log)(e.stderr);
537
+ (0, _logging.log)(e.stderr);
506
538
  }
507
539
  break;
508
540
  case "node:edit":
@@ -627,8 +659,9 @@ async function siteCommandDetected(commandRun) {
627
659
  }
628
660
  // if we have content (meaning it's not blank) then try to write the page location
629
661
  if (locationContent && (await page.writeLocation(locationContent))) {
662
+ recipe.log(siteLoggingName, (0, _logging.commandString)(commandRun));
630
663
  if (!commandRun.options.quiet) {
631
- (0, _statements.log)(`node:edit success updated page content: "${page.id}`);
664
+ (0, _logging.log)(`node:edit success updated page content: "${page.id}`);
632
665
  }
633
666
  } else {
634
667
  console.warn(`node:edit failure to write page content : ${page.id}`);
@@ -643,14 +676,15 @@ async function siteCommandDetected(commandRun) {
643
676
  page[commandRun.options.nodeOp] = commandRun.options[commandRun.options.nodeOp];
644
677
  }
645
678
  let resp = await activeHaxsite.updateNode(page);
679
+ recipe.log(siteLoggingName, (0, _logging.commandString)(commandRun));
646
680
  if (commandRun.options.v) {
647
- (0, _statements.log)(resp);
681
+ (0, _logging.log)(resp, 'silly');
648
682
  }
649
683
  }
650
684
  }
651
685
  }
652
686
  } catch (e) {
653
- (0, _statements.log)(e.stderr);
687
+ (0, _logging.log)(e.stderr);
654
688
  }
655
689
  break;
656
690
  case "node:delete":
@@ -686,14 +720,15 @@ async function siteCommandDetected(commandRun) {
686
720
  if (resp.res.data === 500) {
687
721
  console.warn(`node:delete failed "${commandRun.options.itemId} not found`);
688
722
  } else {
689
- (0, _statements.log)(`"${commandRun.options.itemId}" deleted`);
723
+ recipe.log(siteLoggingName, (0, _logging.commandString)(commandRun));
724
+ (0, _logging.log)(`"${commandRun.options.itemId}" deleted`);
690
725
  }
691
726
  } else {
692
- (0, _statements.log)(`Delete operation canceled`);
727
+ (0, _logging.log)(`Delete operation canceled`);
693
728
  }
694
729
  }
695
730
  } catch (e) {
696
- (0, _statements.log)(e.stderr);
731
+ (0, _logging.log)(e.stderr);
697
732
  }
698
733
  break;
699
734
  case "site:sync":
@@ -701,7 +736,7 @@ async function siteCommandDetected(commandRun) {
701
736
  try {
702
737
  await exec(`cd ${activeHaxsite.directory} && git pull && git push`);
703
738
  } catch (e) {
704
- (0, _statements.log)(e.stderr);
739
+ (0, _logging.log)(e.stderr);
705
740
  }
706
741
  break;
707
742
  case "site:theme":
@@ -721,10 +756,11 @@ async function siteCommandDetected(commandRun) {
721
756
  if (themes && commandRun.options.theme && themes[commandRun.options.theme]) {
722
757
  activeHaxsite.manifest.metadata.theme = themes[commandRun.options.theme];
723
758
  activeHaxsite.manifest.save(false);
759
+ recipe.log(siteLoggingName, (0, _logging.commandString)(commandRun));
724
760
  }
725
761
  }
726
762
  } catch (e) {
727
- (0, _statements.log)(e.stderr);
763
+ (0, _logging.log)(e.stderr);
728
764
  }
729
765
  break;
730
766
  case "site:surge":
@@ -736,7 +772,7 @@ async function siteCommandDetected(commandRun) {
736
772
  s.start((0, _statements.merlinSays)('Installing Surge.sh globally so we can publish'));
737
773
  let execOutput = await exec(`npm install --global surge`);
738
774
  s.stop((0, _statements.merlinSays)('surge.sh installed globally'));
739
- (0, _statements.log)(execOutput.stdout.trim());
775
+ (0, _logging.log)(execOutput.stdout.trim());
740
776
  sysSurge = true;
741
777
  }
742
778
  if (!commandRun.options.domain) {
@@ -753,10 +789,10 @@ async function siteCommandDetected(commandRun) {
753
789
  });
754
790
  }
755
791
  let execOutput = await exec(`cd ${activeHaxsite.directory} && surge . ${commandRun.options.domain}`);
756
- (0, _statements.log)(execOutput.stdout.trim());
757
- (0, _statements.log)(`Site published: https://${commandRun.options.domain}`);
792
+ (0, _logging.log)(execOutput.stdout.trim());
793
+ (0, _logging.log)(`Site published: https://${commandRun.options.domain}`);
758
794
  } catch (e) {
759
- (0, _statements.log)(e.stderr);
795
+ (0, _logging.log)(e.stderr);
760
796
  }
761
797
  break;
762
798
  case "site:file-list":
@@ -766,9 +802,9 @@ async function siteCommandDetected(commandRun) {
766
802
  filename: commandRun.options.filename
767
803
  }, res);
768
804
  if (commandRun.options.format === 'yaml') {
769
- (0, _statements.log)((0, _jsYaml.dump)(res.data));
805
+ (0, _logging.log)((0, _jsYaml.dump)(res.data));
770
806
  } else {
771
- (0, _statements.log)(res.data);
807
+ (0, _logging.log)(res.data);
772
808
  }
773
809
  break;
774
810
  case "site:html":
@@ -811,9 +847,9 @@ async function siteCommandDetected(commandRun) {
811
847
  }
812
848
  } else {
813
849
  if (commandRun.options.format === 'yaml') {
814
- (0, _statements.log)((0, _jsYaml.dump)(els));
850
+ (0, _logging.log)((0, _jsYaml.dump)(els));
815
851
  } else {
816
- (0, _statements.log)(els);
852
+ (0, _logging.log)(els);
817
853
  }
818
854
  }
819
855
  } else {
@@ -829,19 +865,67 @@ async function siteCommandDetected(commandRun) {
829
865
  if (commandRun.options.toFile) {
830
866
  fs.writeFileSync(commandRun.options.toFile, resp.res.data.data);
831
867
  if (!commandRun.options.quiet) {
832
- (0, _statements.log)(`${commandRun.options.toFile} written`);
868
+ (0, _logging.log)(`${commandRun.options.toFile} written`);
833
869
  }
834
870
  } else {
835
- (0, _statements.log)(resp.res.data.data);
871
+ (0, _logging.log)(resp.res.data.data);
836
872
  }
837
873
  } else {
838
874
  if (commandRun.options.toFile) {
839
875
  fs.writeFileSync(commandRun.options.toFile, siteContent);
840
876
  if (!commandRun.options.quiet) {
841
- (0, _statements.log)(`${commandRun.options.toFile} written`);
877
+ (0, _logging.log)(`${commandRun.options.toFile} written`);
842
878
  }
843
879
  } else {
844
- (0, _statements.log)(siteContent);
880
+ (0, _logging.log)(siteContent);
881
+ }
882
+ }
883
+ }
884
+ break;
885
+ // @todo need to make these work..
886
+ case "recipe:read":
887
+ // just print the recipe out
888
+ if (fs.existsSync(path.join(process.cwd(), `${siteRecipeFile}`))) {
889
+ let recContents = await fs.readFileSync(path.join(process.cwd(), `${siteRecipeFile}`), 'utf8');
890
+ console.log(recContents);
891
+ }
892
+ break;
893
+ case "recipe:play":
894
+ // step through and run each recipe once fed a file location
895
+ // this allows for storing commands from a site and then replaying them with ease
896
+ if (!commandRun.options.recipe) {
897
+ commandRun.options.recipe = await p.text({
898
+ message: `Select recipe:`,
899
+ defaultValue: process.cwd(),
900
+ initialValue: process.cwd(),
901
+ validate: val => {
902
+ if (!val.endsWith('.recipe')) {
903
+ return 'HAX Recipe files must end in .recipe';
904
+ }
905
+ }
906
+ });
907
+ }
908
+ if (fs.existsSync(commandRun.options.recipe)) {
909
+ let recContents = await fs.readFileSync(commandRun.options.recipe, 'utf8');
910
+ // split into commands
911
+ let commandList = recContents.replaceAll('cli: ', '').split("\n");
912
+ // confirm each command or allow --y so that it auto applies
913
+ for (var i in commandList) {
914
+ // verify every command starts this way for safety
915
+ if (commandList[i].startsWith('hax site')) {
916
+ let confirmation;
917
+ if (commandRun.options.y) {
918
+ confirmation = true;
919
+ } else {
920
+ confirmation = await p.confirm({
921
+ message: `Do you want to run ${commandList[i]}? (This cannot be undone)`,
922
+ initialValue: true
923
+ });
924
+ }
925
+ // confirmed; let's run!
926
+ if (confirmation) {
927
+ await exec(`${commandList[i]} --y --no-i --auto --quiet`);
928
+ }
845
929
  }
846
930
  }
847
931
  }
@@ -852,7 +936,7 @@ async function siteCommandDetected(commandRun) {
852
936
  break;
853
937
  }
854
938
  // y or noi need to act like it ran and finish instead of looping options
855
- if (commandRun.options.y || !commandRun.options.i) {
939
+ if (commandRun.options.y || !commandRun.options.i || !actionAssigned) {
856
940
  process.exit(0);
857
941
  }
858
942
  operation.action = null;
@@ -953,6 +1037,7 @@ async function openApiBroker(scope, call, body) {
953
1037
  async function siteProcess(commandRun, project, port = '3000') {
954
1038
  // auto select operations to perform if requested
955
1039
  var s = p.spinner();
1040
+ // if we have no extras, or they are empty then set for launch
956
1041
  if (!project.extras) {
957
1042
  project.extras = [];
958
1043
  if (commandRun.options.i) {
@@ -1080,11 +1165,26 @@ async function siteProcess(commandRun, project, port = '3000') {
1080
1165
  await hax.RoutesMap.post.createSite({
1081
1166
  body: siteRequest
1082
1167
  }, res);
1168
+ // path different for this one as it's on the fly produced
1169
+ const recipeFileName = path.join(project.path, '/', project.name, `${siteRecipeFile}`);
1170
+ const recipeLogTransport = new winston.transports.File({
1171
+ filename: recipeFileName
1172
+ });
1173
+ const recipe = winston.createLogger({
1174
+ levels: logLevels,
1175
+ level: siteLoggingName,
1176
+ transports: [recipeLogTransport],
1177
+ format: winston.format.simple()
1178
+ });
1179
+ // matching the common object elsewhere tho different reference in this command since it creates from nothing
1180
+ // capture this if use input on the fly
1181
+ commandRun.options.theme = project.theme;
1182
+ recipe.log(siteLoggingName, (0, _logging.commandString)(commandRun));
1083
1183
  if (commandRun.options.v) {
1084
1184
  if (commandRun.options.format === 'yaml') {
1085
- (0, _statements.log)((0, _jsYaml.dump)(res.data));
1185
+ (0, _logging.log)((0, _jsYaml.dump)(res.data), 'silly');
1086
1186
  } else {
1087
- (0, _statements.log)(res.data);
1187
+ (0, _logging.log)(res.data, 'silly');
1088
1188
  }
1089
1189
  }
1090
1190
  if (!commandRun.options.quiet) {
@@ -1098,7 +1198,7 @@ async function siteProcess(commandRun, project, port = '3000') {
1098
1198
  }
1099
1199
  // options for install, git and other extras
1100
1200
  // can't launch if we didn't install first so launch implies installation
1101
- if (project.extras.includes('launch')) {
1201
+ if (project.extras && project.extras.includes && project.extras.includes('launch')) {
1102
1202
  let optionPath = `${project.path}/${project.name}`;
1103
1203
  let command = `npx @haxtheweb/haxcms-nodejs`;
1104
1204
  if (!commandRun.options.quiet) {
@@ -13,6 +13,7 @@ var ejs = _interopRequireWildcard(require("ejs"));
13
13
  var p = _interopRequireWildcard(require("@clack/prompts"));
14
14
  var _picocolors = _interopRequireDefault(require("picocolors"));
15
15
  var _statements = require("../statements.js");
16
+ var _logging = require("../logging.js");
16
17
  var _utils = require("../utils.js");
17
18
  var hax = _interopRequireWildcard(require("@haxtheweb/haxcms-nodejs"));
18
19
  var child_process = _interopRequireWildcard(require("child_process"));
@@ -150,7 +151,7 @@ async function webcomponentProcess(commandRun, project, port = "8000") {
150
151
  // values not set by user but used in templating
151
152
  project.className = (0, _utils.dashToCamel)(project.name);
152
153
  // option to build github repo link for the user
153
- if (project.extras.includes('git')) {
154
+ if (project.extras && project.extras.includes('git')) {
154
155
  // @todo need to support git@ and https methods
155
156
  if (commandRun.options.auto) {
156
157
  project.gitRepo = `https://github.com/${project.author}/${project.name}.git`;
@@ -227,7 +228,7 @@ async function webcomponentProcess(commandRun, project, port = "8000") {
227
228
  }
228
229
  // options for install, git and other extras
229
230
  // can't launch if we didn't install first so launch implies installation
230
- if (project.extras.includes('launch') || project.extras.includes('install')) {
231
+ if (project.extras && (project.extras.includes('launch') || project.extras.includes('install'))) {
231
232
  s.start((0, _statements.merlinSays)(`Installation magic (${commandRun.options.npmClient} install)`));
232
233
  try {
233
234
  // monorepos install from top but then still need to launch from local location
@@ -240,7 +241,7 @@ async function webcomponentProcess(commandRun, project, port = "8000") {
240
241
  s.stop((0, _statements.merlinSays)(`Everything is installed. It's go time`));
241
242
  }
242
243
  // autolaunch if default was selected
243
- if (project.extras.includes('launch')) {
244
+ if (project.extras && project.extras.includes('launch')) {
244
245
  let optionPath = `${project.path}/${project.name}`;
245
246
  let command = `${commandRun.options.npmClient} start`;
246
247
  p.note(`${(0, _statements.merlinSays)(`I have summoned a sub-process daemon 👹`)}
@@ -331,7 +332,7 @@ async function webcomponentGenerateHAXSchema(commandRun, packageData) {
331
332
  });
332
333
  let wiring = new HAXWiring();
333
334
  if (commandRun.options.debug) {
334
- (0, _statements.log)(ceFileData);
335
+ (0, _logging.log)(ceFileData, 'debug');
335
336
  }
336
337
  if (ceFileData) {
337
338
  let ce = JSON.parse(ceFileData);
@@ -387,10 +388,10 @@ async function webcomponentGenerateHAXSchema(commandRun, packageData) {
387
388
  }
388
389
  });
389
390
  if (commandRun.options.v) {
390
- (0, _statements.log)(JSON.stringify(props, null, 2));
391
+ (0, _logging.log)(JSON.stringify(props, null, 2), 'silly');
391
392
  }
392
393
  fs.writeFileSync(`./lib/${declarations.tagName}.haxProperties.json`, JSON.stringify(props, null, 2));
393
- (0, _statements.log)(`schema written to: ./lib/${declarations.tagName}.haxProperties.json`);
394
+ (0, _logging.log)(`schema written to: ./lib/${declarations.tagName}.haxProperties.json`);
394
395
  });
395
396
  });
396
397
  }
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.communityStatement = communityStatement;
7
7
  exports.haxIntro = haxIntro;
8
- exports.log = log;
9
8
  exports.merlinSays = merlinSays;
10
9
  var _art = require("./art.js");
11
10
  var p = _interopRequireWildcard(require("@clack/prompts"));
@@ -14,12 +13,6 @@ var _promises = require("node:timers/promises");
14
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
14
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
16
15
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
- // wrapper so we can silence all log messages at the same time
18
- function log(msg, level = 'log') {
19
- if (!process.haxquiet) {
20
- console[level](msg);
21
- }
22
- }
23
16
  async function haxIntro() {
24
17
  console.clear();
25
18
  await (0, _promises.setTimeout)(10);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haxtheweb/create",
3
- "version": "9.0.22",
3
+ "version": "9.0.24",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -51,7 +51,8 @@
51
51
  "node-html-parser": "6.1.13",
52
52
  "ejs": "3.1.10",
53
53
  "js-yaml": "4.1.0",
54
- "picocolors": "1.0.1"
54
+ "picocolors": "1.0.1",
55
+ "winston": "3.17.0"
55
56
  },
56
57
  "devDependencies": {
57
58
  "@babel/cli": "^7.24.6",