@haxtheweb/create 9.0.5 → 9.0.7

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
@@ -15,6 +15,9 @@ npx @haxtheweb/create
15
15
  npm init @haxtheweb
16
16
  ```
17
17
 
18
+ ## Windows problems?
19
+ Try setting a different cache path to load from `npm config set cache C:\tmp\nodejs\npm-cache --global`
20
+
18
21
  Follow the prompts and let's HAX the Web together!
19
22
 
20
23
  ## Web component
package/dist/create.js CHANGED
@@ -4,15 +4,16 @@
4
4
 
5
5
  var fs = _interopRequireWildcard(require("node:fs"));
6
6
  var path = _interopRequireWildcard(require("node:path"));
7
- var hax = _interopRequireWildcard(require("@haxtheweb/haxcms-nodejs"));
8
- var _art = require("./art.js");
9
- var _utils = require("./utils.js");
10
7
  var _promises = require("node:timers/promises");
11
8
  var ejs = _interopRequireWildcard(require("ejs"));
12
9
  var p = _interopRequireWildcard(require("@clack/prompts"));
13
10
  var _picocolors = _interopRequireDefault(require("picocolors"));
11
+ var _statements = require("./lib/statements.js");
12
+ var _utils = require("./lib/utils.js");
13
+ var hax = _interopRequireWildcard(require("@haxtheweb/haxcms-nodejs"));
14
14
  var child_process = _interopRequireWildcard(require("child_process"));
15
15
  var util = _interopRequireWildcard(require("node:util"));
16
+ var _commander = require("commander");
16
17
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
18
  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); }
18
19
  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; }
@@ -23,121 +24,180 @@ const fakeSend = {
23
24
  send: json => console.log(json),
24
25
  sendStatus: data => console.log(data)
25
26
  };
26
- // standardize merlin statements visually
27
- function merlinSays(text) {
28
- return `${_picocolors.default.yellow(_picocolors.default.bgBlack(` 🧙 Merlin: `))} ${_picocolors.default.bgBlack(_picocolors.default.green(` ${text} `))}`;
29
- }
27
+ var hasGit = true;
28
+ exec('git --version', error => {
29
+ if (error) {
30
+ hasGit = false;
31
+ }
32
+ });
33
+ var hasSurge = true;
34
+ exec('surge --version', error => {
35
+ if (error) {
36
+ hasSurge = false;
37
+ }
38
+ });
30
39
  async function main() {
31
- console.clear();
32
- p.intro(`${_picocolors.default.bgBlack(_picocolors.default.underline(_picocolors.default.gray(`Never`)))}`);
33
- await (0, _promises.setTimeout)(300);
34
- p.intro(`${_picocolors.default.bgBlack(_picocolors.default.red(` stop `))}`);
35
- await (0, _promises.setTimeout)(300);
36
- p.intro(`${_picocolors.default.bgBlack(_picocolors.default.white(` never`))}`);
37
- await (0, _promises.setTimeout)(300);
38
- p.intro(`${_picocolors.default.bgBlack(_picocolors.default.cyan(` stopping `))}`);
39
- await (0, _promises.setTimeout)(500);
40
- let colors = ['blue', 'yellow', 'red', 'magenta'];
41
- for (let i in _art.characters) {
42
- if (i < _art.characters.length - 1) {
43
- console.clear();
44
- p.intro(`${_picocolors.default.bgBlack(_picocolors.default[colors[i]](`Better future loading..`))}`);
45
- p.intro(_picocolors.default.bgBlack(_picocolors.default[colors[i]](_art.characters[i])));
46
- let rockets = '';
47
- for (let step = 0; step < i; step++) {
48
- rockets += "🚀🚀🚀";
49
- }
50
- p.intro(rockets);
51
- await (0, _promises.setTimeout)(Math.random() * 400 + 150);
40
+ _commander.program.option('--y') // skip steps
41
+ .option('--skip') // skip steps
42
+ .option('--auto') // select defaults whenever possible
43
+ .option('--type <char>') // haxsite, webcomponent
44
+ .option('--name <char>') // project name
45
+ .option('--org <char>') // organization name
46
+ .option('--author <char>') // organization name
47
+ .option('--path <char>') // path
48
+ .option('--npmClient <char>') // npm yarn pnpm etc
49
+ .option('--');
50
+ _commander.program.parse();
51
+ var cliOptions = _commander.program.opts();
52
+ // auto and y assume same thing
53
+ if (cliOptions.y || cliOptions.auto) {
54
+ cliOptions.y = true;
55
+ cliOptions.auto = true;
56
+ // assume we are creating a webcomponent if name supplied but no type defined
57
+ if (!cliOptions.type) {
58
+ cliOptions.type = 'webcomponent';
52
59
  }
53
60
  }
54
- console.clear();
55
- p.intro(_picocolors.default.bgBlack(_picocolors.default.green(_art.characters.pop())));
56
- p.intro(`${_picocolors.default.bgGreen(_picocolors.default.black(` The Web : CLI `))}
57
-
58
-
59
- ${merlinSays('Welcome wary web wanderer')}`);
60
- // should be able to grab
61
+ if (!cliOptions.y && !cliOptions.auto && !cliOptions.skip) {
62
+ await (0, _statements.haxIntro)();
63
+ }
64
+ if (!cliOptions.npmClient) {
65
+ cliOptions.npmClient = 'npm';
66
+ }
61
67
  let author = '';
68
+ // should be able to grab if not predefined
62
69
  try {
63
70
  let value = await exec(`git config user.name`);
64
71
  author = value.stdout.trim();
65
72
  } catch (e) {
66
- console.log(e);
73
+ console.log('git user name not configured. Run the following to do this:');
74
+ console.log('git config --global user.name "namehere"');
75
+ console.log('git config --global user.email "email@here');
76
+ }
77
+ if (cliOptions.auto) {
78
+ cliOptions.path = process.cwd();
79
+ cliOptions.org = '';
80
+ cliOptions.author = author;
67
81
  }
68
82
  var port = "3000";
69
83
  // delay so that we clear and then let them visually react to change
70
84
  const siteData = await hax.systemStructureContext();
85
+ let packageData = {};
86
+ let testPackages = [path.join(process.cwd(), 'package.json'), path.join(process.cwd(), '../', 'package.json'), path.join(process.cwd(), '../', '../', 'package.json')];
87
+ // test within reason, for package.json files seeing if anything is available to suggest
88
+ // that we might be in a local package or a monorepo.
89
+ while (testPackages.length > 0) {
90
+ let packLoc = testPackages.shift();
91
+ if (fs.existsSync(packLoc)) {
92
+ try {
93
+ packageData = JSON.parse(fs.readFileSync(`${process.cwd()}/package.json`));
94
+ // assume we are working on a web component / existing if we find this key
95
+ if (packageData.hax && packageData.hax.cli) {
96
+ cliOptions.type = 'webcomponent';
97
+ }
98
+ // leverage these values if they exist downstream
99
+ if (packageData.npmClient) {
100
+ cliOptions.npmClient = packageData.npmClient;
101
+ }
102
+ // see if we're in a monorepo
103
+ if (packageData.useWorkspaces && packageData.workspaces && packageData.workspaces.packages && packageData.workspaces.packages[0]) {
104
+ p.intro(`${_picocolors.default.bgBlack(_picocolors.default.white(` Monorepo detected : Setting relative defaults `))}`);
105
+ cliOptions.isMonorepo = true;
106
+ cliOptions.auto = true;
107
+ // assumed if monorepo
108
+ cliOptions.type = 'webcomponent';
109
+ cliOptions.path = path.join(process.cwd(), packageData.workspaces.packages[0].replace('/*', ''));
110
+ if (packageData.orgNpm) {
111
+ cliOptions.org = packageData.orgNpm;
112
+ }
113
+ cliOptions.gitRepo = packageData.repository.url;
114
+ cliOptions.author = packageData.author.name ? packageData.author.name : author;
115
+ }
116
+ } catch (err) {
117
+ console.error(err);
118
+ }
119
+ }
120
+ }
71
121
  // delay so that we clear and then let them visually react to change
72
122
  // CLI works within context of the site if one is detected, otherwise we can do other thingss
73
123
  if (siteData) {
74
124
  p.intro(`${_picocolors.default.bgBlack(_picocolors.default.white(` HAXTheWeb : Site detected `))}`);
75
- p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Title: ${siteData.site.title} `))}`);
125
+ p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Name: ${siteData.name} `))}`);
76
126
  let operation = {
77
127
  action: null
78
128
  };
79
129
  // infinite loop until quitting the cli
80
130
  while (operation.action !== 'quit') {
131
+ let actions = [{
132
+ value: 'status',
133
+ label: "Site Status"
134
+ }, {
135
+ value: 'localhost',
136
+ label: "Open Site (localhost)"
137
+ }, {
138
+ value: 'sync-git',
139
+ label: "Sync code in git"
140
+ }
141
+ //{ value: 'node-add', label: "New Page"},
142
+ ];
143
+ if (hasSurge) {
144
+ actions.push({
145
+ value: 'publish-surge',
146
+ label: "Publish site using Surge.sh"
147
+ });
148
+ }
149
+ actions.push({
150
+ value: 'quit',
151
+ label: "🚪 Quit"
152
+ });
81
153
  operation = await p.group({
82
154
  action: ({
83
155
  results
84
156
  }) => p.select({
85
157
  message: `Actions you can take`,
86
- options: [{
87
- value: 'stats',
88
- label: "Site stats"
89
- }, {
90
- value: 'localhost',
91
- label: "Open Site (localhost)"
92
- }, {
93
- value: 'node-add',
94
- label: "New Page"
95
- }, {
96
- value: 'sync-git',
97
- label: "Sync code in git"
98
- }, {
99
- value: 'publish',
100
- label: "Publish site to the web"
101
- }, {
102
- value: 'quit',
103
- label: "🚪 Quit"
104
- }]
158
+ options: actions
105
159
  })
106
160
  }, {
107
161
  onCancel: () => {
108
162
  p.cancel('🧙 Merlin: Canceling CLI.. HAX ya later 🪄');
109
- communityStatement();
163
+ (0, _statements.communityStatement)();
110
164
  process.exit(0);
111
165
  }
112
166
  });
113
167
  switch (operation.action) {
114
- case "stats":
115
- p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Title: ${siteData.site.title} `))}`);
116
- p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Description: ${siteData.site.description} `))}`);
117
- p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Pages: ${siteData.site.items.length} `))}`);
168
+ case "status":
169
+ p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Title: ${siteData.manifest.title} `))}`);
170
+ p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Description: ${siteData.manifest.description} `))}`);
171
+ p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Pages: ${siteData.manifest.items.length} `))}`);
118
172
  break;
119
173
  case "localhost":
120
174
  try {
121
- await exec(`cd ${siteData.path} && npx @haxtheweb/haxcms-nodejs`);
122
- } catch (e) {}
175
+ await exec(`cd ${siteData.directory} && npx @haxtheweb/haxcms-nodejs`);
176
+ } catch (e) {
177
+ console.log(e.stderr);
178
+ }
123
179
  break;
124
180
  case "node-add":
125
181
  // @todo add new page option
182
+ try {
183
+ //await exec(`${cliOptions.npmClient} run haxcms-nodejs-cli --site=${siteData.name} --op=createNode --nodeTitle=New`);
184
+ } catch (e) {
185
+ console.log(e.stderr);
186
+ }
126
187
  break;
127
188
  case "sync-git":
128
189
  // @todo git sync might need other arguments / be combined with publishing
129
190
  try {
130
- await exec(`cd ${siteData.path} && git pull && git push`);
191
+ await exec(`cd ${siteData.directory} && git pull && git push`);
131
192
  } catch (e) {
132
- console.log(e);
193
+ console.log(e.stderr);
133
194
  }
134
195
  break;
135
- case "publish":
136
- // @todo support other forms of publishing
196
+ case "publish-surge":
137
197
  try {
138
- await exec(`cd ${siteData.path} && npm install --global surge && surge .`);
198
+ await exec(`cd ${siteData.directory} && surge .`);
139
199
  } catch (e) {
140
- console.log(e);
200
+ console.log(e.stderr);
141
201
  }
142
202
  break;
143
203
  case "quit":
@@ -145,6 +205,35 @@ async function main() {
145
205
  break;
146
206
  }
147
207
  }
208
+ } else if (packageData && packageData.hax && packageData.hax.cli && packageData.scripts.start) {
209
+ p.intro(`${_picocolors.default.bgBlack(_picocolors.default.white(` HAXTheWeb : Webcomponent detected `))}`);
210
+ p.intro(`${_picocolors.default.bgBlue(_picocolors.default.white(` Name: ${packageData.name} `))}`);
211
+ port = "8000";
212
+ p.note(`${(0, _statements.merlinSays)(`I have summoned a sub-process daemon 👹`)}
213
+
214
+ 🚀 Running your ${_picocolors.default.bold('webcomponent')} ${_picocolors.default.bold(packageData.name)}:
215
+ ${_picocolors.default.underline(_picocolors.default.cyan(`http://localhost:${port}`))}
216
+
217
+ 🏠 Launched: ${_picocolors.default.underline(_picocolors.default.bold(_picocolors.default.yellow(_picocolors.default.bgBlack(`${process.cwd()}`))))}
218
+ 💻 Folder: ${_picocolors.default.bold(_picocolors.default.yellow(_picocolors.default.bgBlack(`cd ${process.cwd()}`)))}
219
+ 📂 Open folder: ${_picocolors.default.bold(_picocolors.default.yellow(_picocolors.default.bgBlack(`open ${process.cwd()}`)))}
220
+ 📘 VS Code Project: ${_picocolors.default.bold(_picocolors.default.yellow(_picocolors.default.bgBlack(`code ${process.cwd()}`)))}
221
+ 🚧 Launch later: ${_picocolors.default.bold(_picocolors.default.yellow(_picocolors.default.bgBlack(`${cliOptions.npmClient} start`)))}
222
+
223
+ ⌨️ To exit 🧙 Merlin press: ${_picocolors.default.bold(_picocolors.default.black(_picocolors.default.bgRed(` CTRL + C `)))}
224
+ `);
225
+ try {
226
+ // ensure it's installed first, unless it's a monorepo
227
+ if (!cliOptions.isMonorepo) {
228
+ let s = p.spinner();
229
+ s.start((0, _statements.merlinSays)(`Installation magic (${cliOptions.npmClient} install)`));
230
+ await exec(`${cliOptions.npmClient} install`);
231
+ s.stop((0, _statements.merlinSays)(`Everything is installed. It's go time`));
232
+ }
233
+ await exec(`${cliOptions.npmClient} start`);
234
+ } catch (e) {
235
+ // don't log bc output is odd
236
+ }
148
237
  } else {
149
238
  let activeProject = null;
150
239
  let project = {
@@ -153,35 +242,39 @@ async function main() {
153
242
  while (project.type !== 'quit') {
154
243
  if (activeProject) {
155
244
  p.note(` 🧙🪄 BE GONE ${_picocolors.default.bold(_picocolors.default.black(_picocolors.default.bgGreen(activeProject)))} sub-process daemon! 🪄 + ✨ 👹 = 💀 `);
245
+ cliOptions = {};
246
+ }
247
+ if (['haxsite', 'webcomponent'].includes(cliOptions.type)) {
248
+ project = {
249
+ type: cliOptions.type
250
+ };
251
+ } else {
252
+ project = await p.group({
253
+ type: ({
254
+ results
255
+ }) => p.select({
256
+ message: !activeProject ? `What should we build?` : `Thirsty for more? What should we create now?`,
257
+ initialValue: 'webcomponent',
258
+ required: true,
259
+ options: [{
260
+ value: 'webcomponent',
261
+ label: '🏗️ Create a Web Component'
262
+ }, {
263
+ value: 'haxsite',
264
+ label: '🏡 Create a HAXcms site (single)'
265
+ }, {
266
+ value: 'quit',
267
+ label: '🚪 Quit'
268
+ }]
269
+ })
270
+ }, {
271
+ onCancel: () => {
272
+ p.cancel('🧙🪄 Merlin: Leaving so soon? HAX ya later');
273
+ (0, _statements.communityStatement)();
274
+ process.exit(0);
275
+ }
276
+ });
156
277
  }
157
- project = await p.group({
158
- type: ({
159
- results
160
- }) => p.select({
161
- message: !activeProject ? `What should we build?` : `Thirsty for more? What should we create now?`,
162
- initialValue: 'haxcms',
163
- required: true,
164
- options: [{
165
- value: 'haxcms',
166
- label: '🏡 Create a HAXcms site (single)'
167
- }, {
168
- value: 'haxcms-multisite',
169
- label: '🏘️ Create a HAXcms multi-site'
170
- }, {
171
- value: 'webcomponent',
172
- label: '🏗️ Create a Web Component'
173
- }, {
174
- value: 'quit',
175
- label: '🚪 Quit'
176
- }]
177
- })
178
- }, {
179
- onCancel: () => {
180
- p.cancel('🧙🪄 Merlin: Leaving so soon? HAX ya later');
181
- communityStatement();
182
- process.exit(0);
183
- }
184
- });
185
278
  activeProject = project.type;
186
279
  // silly but this way we don't have to take options for quitting
187
280
  if (project.type !== 'quit') {
@@ -197,116 +290,167 @@ async function main() {
197
290
  results
198
291
  }) => {
199
292
  let initialPath = `${process.cwd()}`;
200
- return p.text({
201
- message: `What folder will your ${results.type === "webcomponent" ? "project" : "site"} live in?`,
202
- placeholder: initialPath,
203
- validate: value => {
204
- if (!value) {
205
- return "Path is required (tab writes default)";
293
+ if (!cliOptions.path && !cliOptions.auto) {
294
+ return p.text({
295
+ message: `What folder will your ${cliOptions.type === "webcomponent" || results.type === "webcomponent" ? "project" : "site"} live in?`,
296
+ placeholder: initialPath,
297
+ required: true,
298
+ validate: value => {
299
+ if (!value) {
300
+ return "Path is required (tab writes default)";
301
+ }
302
+ if (!fs.existsSync(value)) {
303
+ return `${value} does not exist. Select a valid folder`;
304
+ }
206
305
  }
207
- if (!fs.existsSync(value)) {
208
- return `${value} does not exist. Select a valid folder`;
209
- }
210
- }
211
- });
306
+ });
307
+ }
212
308
  },
213
309
  name: ({
214
310
  results
215
311
  }) => {
216
- let placeholder = "mysite";
217
- let message = "Site name:";
218
- if (results.type === "webcomponent") {
219
- placeholder = "my-element";
220
- message = "Element name:";
221
- } else if (results.type === "haxcms-multisite") {
222
- placeholder = "mysitefactory";
223
- message = "Site factory name:";
224
- }
225
- return p.text({
226
- message: message,
227
- placeholder: placeholder,
228
- validate: value => {
229
- if (!value) {
230
- return "Name is required (tab writes default)";
231
- }
232
- if (/^\d/.test(value)) {
233
- return "Name cannot start with a number";
234
- }
235
- if (value.indexOf(' ') !== -1) {
236
- return "No spaces allowed in project name";
237
- }
238
- if (results.type === "webcomponent" && value.indexOf('-') === -1 && value.indexOf('-') !== 0 && value.indexOf('-') !== value.length - 1) {
239
- return "Name must include at least one `-` and must not start or end name.";
312
+ if (!cliOptions.name) {
313
+ let placeholder = "mysite";
314
+ let message = "Site name:";
315
+ if (cliOptions.type === "webcomponent" || results.type === "webcomponent") {
316
+ placeholder = "my-element";
317
+ message = "Element name:";
318
+ }
319
+ return p.text({
320
+ message: message,
321
+ placeholder: placeholder,
322
+ required: true,
323
+ validate: value => {
324
+ if (!value) {
325
+ return "Name is required (tab writes default)";
326
+ }
327
+ if (/^\d/.test(value)) {
328
+ return "Name cannot start with a number";
329
+ }
330
+ if (value.indexOf(' ') !== -1) {
331
+ return "No spaces allowed in project name";
332
+ }
333
+ if (results.type === "webcomponent" && value.indexOf('-') === -1 && value.indexOf('-') !== 0 && value.indexOf('-') !== value.length - 1) {
334
+ return "Name must include at least one `-` and must not start or end name.";
335
+ }
336
+ // assumes auto was selected in CLI
337
+ let joint = process.cwd();
338
+ if (cliOptions.path) {
339
+ joint = cliOptions.path;
340
+ } else if (results.path) {
341
+ joint = results.path;
342
+ }
343
+ if (fs.existsSync(path.join(joint, value))) {
344
+ return `${path.join(joint, value)} exists, rename this project`;
345
+ }
240
346
  }
241
- if (fs.existsSync(path.join(results.path, value))) {
242
- return `${path.join(results.path, value)} exists, rename this project`;
347
+ });
348
+ }
349
+ },
350
+ org: ({
351
+ results
352
+ }) => {
353
+ if (results.type === "webcomponent" && !cliOptions.org && !cliOptions.auto) {
354
+ // @todo detect mono repo and automatically add this
355
+ let initialOrg = '@yourOrganization';
356
+ return p.text({
357
+ message: 'Organization:',
358
+ placeholder: initialOrg,
359
+ required: false,
360
+ validate: value => {
361
+ if (value && !value.startsWith('@')) {
362
+ return "Organizations are not required, but organizations must start with @ if used";
363
+ }
243
364
  }
244
- }
245
- });
365
+ });
366
+ }
246
367
  },
247
368
  author: ({
248
369
  results
249
370
  }) => {
250
- return p.text({
251
- message: 'Author:',
252
- initialValue: author
253
- });
371
+ if (!cliOptions.author && !cliOptions.auto) {
372
+ return p.text({
373
+ message: 'Author:',
374
+ required: false,
375
+ initialValue: author
376
+ });
377
+ }
254
378
  },
255
379
  extras: ({
256
380
  results
257
381
  }) => {
258
- let options = [];
259
- let initialValues = [];
260
- if (results.type === "webcomponent") {
261
- options = [{
262
- value: 'launch',
263
- label: 'Launch project',
264
- hint: 'recommended, requires install'
265
- }, {
266
- value: 'install',
267
- label: 'Install dependencies via npm',
268
- hint: 'recommended'
269
- }, {
270
- value: 'git',
271
- label: 'Apply version control via git',
272
- hint: 'recommended'
273
- }];
274
- initialValues = ['launch', 'install', 'git'];
275
- } else {
276
- options = [{
277
- value: 'launch',
278
- label: 'Launch project on creation',
279
- hint: 'recommended'
280
- }];
281
- initialValues = ['launch'];
382
+ if (!cliOptions.auto && !cliOptions.skip) {
383
+ let options = [];
384
+ let initialValues = [];
385
+ if (cliOptions.type === "webcomponent" || results.type === "webcomponent") {
386
+ options = [{
387
+ value: 'launch',
388
+ label: 'Launch project',
389
+ hint: 'recommended'
390
+ }, {
391
+ value: 'install',
392
+ label: `Install dependencies via ${cliOptions.npmClient}`,
393
+ hint: 'recommended'
394
+ }, {
395
+ value: 'git',
396
+ label: 'Apply version control via git',
397
+ hint: 'recommended'
398
+ }];
399
+ initialValues = ['launch', 'install', 'git'];
400
+ if (!hasGit || cliOptions.isMonorepo) {
401
+ options.pop();
402
+ initialValues.pop();
403
+ }
404
+ } else {
405
+ options = [{
406
+ value: 'launch',
407
+ label: 'Launch project on creation',
408
+ hint: 'recommended'
409
+ }];
410
+ initialValues = ['launch'];
411
+ }
412
+ return p.multiselect({
413
+ message: 'Additional setup',
414
+ initialValues: initialValues,
415
+ options: options,
416
+ required: false
417
+ });
282
418
  }
283
- return p.multiselect({
284
- message: 'Additional setup',
285
- initialValues: initialValues,
286
- options: options,
287
- required: false
288
- });
289
419
  }
290
420
  }, {
291
421
  onCancel: () => {
292
422
  p.cancel('🧙🪄 Merlin: Canceling CLI.. HAX ya later');
293
- communityStatement();
423
+ (0, _statements.communityStatement)();
294
424
  process.exit(0);
295
425
  }
296
426
  });
427
+ // merge cli options with project options assume this is NOT a monorepo
428
+ // but spread will overwrite if needed
429
+ project = {
430
+ isMonorepo: false,
431
+ ...project,
432
+ ...cliOptions
433
+ };
434
+ // auto select operations to perform if requested
435
+ if (project.auto) {
436
+ let extras = ['launch'];
437
+ if (project.type === "webcomponent") {
438
+ extras = ['launch', 'install', 'git'];
439
+ if (!hasGit || project.isMonorepo) {
440
+ extras.pop();
441
+ }
442
+ }
443
+ project.extras = extras;
444
+ }
297
445
  // values not set by user but used in templating
298
446
  project.className = (0, _utils.dashToCamel)(project.name);
299
447
  project.year = new Date().getFullYear();
300
448
  project.version = await HAXCMS.getHAXCMSVersion();
301
449
  let s = p.spinner();
302
- // we can do this if it's a multisite
303
- var site;
304
450
  // resolve site vs multi-site
305
451
  switch (project.type) {
306
- case 'haxcms':
307
- s.start(merlinSays(`Creating new site: ${project.name}`));
308
- //site = new hax.HAXCMSSite();
309
- //await site.newSite(project.path, '/', project.name);
452
+ case 'haxsite':
453
+ s.start((0, _statements.merlinSays)(`Creating new site: ${project.name}`));
310
454
  let siteRequest = {
311
455
  "site": {
312
456
  "name": project.name,
@@ -328,23 +472,22 @@ async function main() {
328
472
  await hax.RoutesMap.post.createSite({
329
473
  body: siteRequest
330
474
  }, fakeSend);
331
- s.stop(merlinSays(`${project.name} created!`));
332
- await (0, _promises.setTimeout)(500);
333
- break;
334
- case 'haxcms-multisite':
335
- s.start(merlinSays(`Creating multisite: ${project.name}`));
336
- await fs.mkdirSync(`${project.path}/${project.name}`);
337
- s.stop(merlinSays(`${project.name} is setup to be a multi-site!`));
475
+ s.stop((0, _statements.merlinSays)(`${project.name} created!`));
338
476
  await (0, _promises.setTimeout)(500);
339
477
  break;
340
478
  case 'webcomponent':
341
479
  port = "8000";
342
480
  // option to build github repo link for the user
343
481
  if (project.extras.includes('git')) {
344
- project.gitRepo = await p.text({
345
- message: 'Git Repo location:',
346
- placeholder: `git@github.com:${project.author}/${project.name}.git`
347
- });
482
+ // @todo need to support git@ and https methods
483
+ if (cliOptions.auto) {
484
+ project.gitRepo = `https://github.com/${project.author}/${project.name}.git`;
485
+ } else {
486
+ project.gitRepo = await p.text({
487
+ message: 'Git Repo location:',
488
+ placeholder: `https://github.com/${project.author}/${project.name}.git`
489
+ });
490
+ }
348
491
  // if they supplied one and it has github in it, build a link automatically for ejs index
349
492
  if (project.gitRepo && project.gitRepo.includes('github.com')) {
350
493
  project.githubLink = project.gitRepo.replace('git@github.com:', 'https://github.com/').replace('.git', '');
@@ -354,15 +497,32 @@ async function main() {
354
497
  } else {
355
498
  project.githubLink = null;
356
499
  }
357
- s.start(merlinSays('Copying project files'));
500
+ // if we have an org, add a / at the end so file name is written correctly
501
+ if (project.org) {
502
+ project.org += '/';
503
+ } else {
504
+ project.org = '';
505
+ }
506
+ s.start((0, _statements.merlinSays)('Copying project files'));
358
507
  // leverage this little helper from HAXcms
359
508
  await HAXCMS.recurseCopy(`${process.mainModule.path}/templates/${project.type}/hax/`, `${project.path}/${project.name}`);
360
509
  // rename paths that are of the element name in question
361
- await fs.renameSync(`${project.path}/${project.name}/src/webcomponent.js`, `${project.path}/${project.name}/src/${project.name}.js`);
362
510
  await fs.renameSync(`${project.path}/${project.name}/lib/webcomponent.haxProperties.json`, `${project.path}/${project.name}/lib/${project.name}.haxProperties.json`);
363
- s.stop(merlinSays('Files copied'));
511
+ // loop through and rename all the localization files
512
+ fs.readdir(`${project.path}/${project.name}/locales/`, function (err, files) {
513
+ if (err) {
514
+ console.error("Could not list the directory.", err);
515
+ process.exit(1);
516
+ }
517
+ files.forEach(async function (file, index) {
518
+ await fs.renameSync(`${project.path}/${project.name}/locales/${file}`, `${project.path}/${project.name}/locales/${file.replace('webcomponent', project.name)}`);
519
+ });
520
+ });
521
+ await fs.renameSync(`${project.path}/${project.name}/webcomponent.js`, `${project.path}/${project.name}/${project.name}.js`);
522
+ await fs.renameSync(`${project.path}/${project.name}/test/webcomponent.test.js`, `${project.path}/${project.name}/test/${project.name}.test.js`);
523
+ s.stop((0, _statements.merlinSays)('Files copied'));
364
524
  await (0, _promises.setTimeout)(500);
365
- s.start(merlinSays('Making files awesome'));
525
+ s.start((0, _statements.merlinSays)('Making files awesome'));
366
526
  for (const filePath of (0, _utils.readAllFiles)(`${project.path}/${project.name}`)) {
367
527
  try {
368
528
  // ensure we don't try to pattern rewrite image files
@@ -380,7 +540,7 @@ async function main() {
380
540
  s.stop('Files are now awesome!');
381
541
  break;
382
542
  }
383
- if (project.gitRepo) {
543
+ if (project.gitRepo && !cliOptions.isMonorepo) {
384
544
  try {
385
545
  await exec(`cd ${project.path}/${project.name} && git init && git add -A && git commit -m "first commit" && git branch -M main${project.gitRepo ? ` && git remote add origin ${project.gitRepo}` : ''}`);
386
546
  } catch (e) {}
@@ -388,22 +548,25 @@ async function main() {
388
548
  // options for install, git and other extras
389
549
  // can't launch if we didn't install first so launch implies installation
390
550
  if (project.extras.includes('launch') || project.extras.includes('install')) {
391
- s.start(merlinSays(`Installation magic (npm install)`));
551
+ s.start((0, _statements.merlinSays)(`Installation magic (${cliOptions.npmClient} install)`));
392
552
  try {
393
- await exec(`cd ${project.path}/${project.name} && npm install`);
553
+ // monorepos install from top but then still need to launch from local location
554
+ if (!cliOptions.isMonorepo) {
555
+ await exec(`cd ${project.path}/${project.name} && ${cliOptions.npmClient} install`);
556
+ }
394
557
  } catch (e) {
395
558
  console.log(e);
396
559
  }
397
- s.stop(merlinSays(`Everything is installed. It's go time`));
560
+ s.stop((0, _statements.merlinSays)(`Everything is installed. It's go time`));
398
561
  }
399
562
  // autolaunch if default was selected
400
563
  if (project.extras.includes('launch')) {
401
564
  let optionPath = `${project.path}/${project.name}`;
402
565
  let command = `npx @haxtheweb/haxcms-nodejs`;
403
566
  if (project.type === "webcomponent") {
404
- command = `npm start`;
567
+ command = `${cliOptions.npmClient} start`;
405
568
  }
406
- p.note(`${merlinSays(`I have summoned a sub-process daemon 👹`)}
569
+ p.note(`${(0, _statements.merlinSays)(`I have summoned a sub-process daemon 👹`)}
407
570
 
408
571
  🚀 Running your ${_picocolors.default.bold(project.type)} ${_picocolors.default.bold(project.name)}:
409
572
  ${_picocolors.default.underline(_picocolors.default.cyan(`http://localhost:${port}`))}
@@ -426,14 +589,11 @@ async function main() {
426
589
  } else {
427
590
  let nextSteps = `cd ${project.path}/${project.name} && `;
428
591
  switch (project.type) {
429
- case 'haxcms':
592
+ case 'haxsite':
430
593
  nextSteps += `npx @haxtheweb/haxcms-nodejs`;
431
594
  break;
432
- case 'haxcms-multisite':
433
- nextSteps = `cd ${project.path} && npx @haxtheweb/haxcms-nodejs\n`;
434
- break;
435
595
  case 'webcomponent':
436
- nextSteps += `${project.extras.includes('install') ? '' : 'npm install &&'}npm start`;
596
+ nextSteps += `${project.extras.includes('install') ? '' : `${cliOptions.npmClient} install && `}${cliOptions.npmClient} start`;
437
597
  break;
438
598
  }
439
599
  p.note(`${project.name} is ready to go. Run the following to start development:`);
@@ -442,23 +602,6 @@ async function main() {
442
602
  }
443
603
  }
444
604
  }
445
- communityStatement();
605
+ (0, _statements.communityStatement)();
446
606
  }
447
- main().catch(console.error);
448
-
449
- // standard community statement so we can leverage on cancel executions
450
- function communityStatement() {
451
- p.outro(`
452
- 🧙 HAX @ Penn State: ${_picocolors.default.underline(_picocolors.default.cyan('https://hax.psu.edu'))}
453
-
454
- 🔮 Ideas to HAX Harder, Better, Faster, Stronger: ${_picocolors.default.underline(_picocolors.default.white('https://github.com/haxtheweb/issues/issues'))}
455
-
456
- 👔 Share on LinkedIn: ${_picocolors.default.underline(_picocolors.default.cyan('https://bit.ly/hax-the-linkedin'))}
457
-
458
- 🧵 Tweet on X: ${_picocolors.default.underline(_picocolors.default.white('https://bit.ly/hax-the-x'))}
459
-
460
- 💬 Join Community: ${_picocolors.default.underline(_picocolors.default.cyan('https://bit.ly/hax-discord'))}
461
-
462
- 💡 ${_picocolors.default.bold(_picocolors.default.white(`Never. Stop. Innovating.`))}
463
- `);
464
- }
607
+ main().catch(console.error);
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.communityStatement = communityStatement;
7
+ exports.haxIntro = haxIntro;
8
+ exports.merlinSays = merlinSays;
9
+ var _art = require("./art.js");
10
+ var p = _interopRequireWildcard(require("@clack/prompts"));
11
+ var _picocolors = _interopRequireDefault(require("picocolors"));
12
+ var _promises = require("node:timers/promises");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
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); }
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; }
16
+ async function haxIntro() {
17
+ console.clear();
18
+ await (0, _promises.setTimeout)(10);
19
+ console.clear();
20
+ p.intro(`${_picocolors.default.bgBlack(_picocolors.default.underline(_picocolors.default.gray(`Never`)))}`);
21
+ await (0, _promises.setTimeout)(100);
22
+ p.intro(`${_picocolors.default.bgBlack(_picocolors.default.red(` stop `))}`);
23
+ await (0, _promises.setTimeout)(300);
24
+ p.intro(`${_picocolors.default.bgBlack(_picocolors.default.white(` never`))}`);
25
+ await (0, _promises.setTimeout)(300);
26
+ p.intro(`${_picocolors.default.bgBlack(_picocolors.default.cyan(` stopping `))}`);
27
+ await (0, _promises.setTimeout)(500);
28
+ let colors = ['blue', 'yellow', 'red', 'magenta'];
29
+ for (let i in _art.characters) {
30
+ if (i < _art.characters.length - 1) {
31
+ console.clear();
32
+ p.intro(`${_picocolors.default.bgBlack(_picocolors.default[colors[i]](`Better future loading..`))}`);
33
+ p.intro(_picocolors.default.bgBlack(_picocolors.default[colors[i]](_art.characters[i])));
34
+ let rockets = '';
35
+ for (let step = 0; step < i; step++) {
36
+ rockets += "🚀🚀🚀";
37
+ }
38
+ p.intro(rockets);
39
+ await (0, _promises.setTimeout)(Math.random() * 400 + 150);
40
+ }
41
+ }
42
+ console.clear();
43
+ p.intro(_picocolors.default.bgBlack(_picocolors.default.green(_art.characters.pop())));
44
+ p.intro(`${_picocolors.default.bgGreen(_picocolors.default.black(` The Web : CLI `))}
45
+
46
+
47
+ ${merlinSays('Welcome wary web wanderer')}`);
48
+ }
49
+
50
+ // standard community statement so we can leverage on cancel executions
51
+ function communityStatement() {
52
+ p.outro(`
53
+ 🧙 HAX @ Penn State: ${_picocolors.default.underline(_picocolors.default.cyan('https://hax.psu.edu'))}
54
+
55
+ 🔮 Ideas to HAX Harder, Better, Faster, Stronger: ${_picocolors.default.underline(_picocolors.default.white('https://github.com/haxtheweb/issues/issues'))}
56
+
57
+ 👔 Share on LinkedIn: ${_picocolors.default.underline(_picocolors.default.cyan('https://bit.ly/hax-the-linkedin'))}
58
+
59
+ 🧵 Tweet on X: ${_picocolors.default.underline(_picocolors.default.white('https://bit.ly/hax-the-x'))}
60
+
61
+ 💬 Join Community: ${_picocolors.default.underline(_picocolors.default.cyan('https://bit.ly/hax-discord'))}
62
+
63
+ 💡 ${_picocolors.default.bold(_picocolors.default.white(`Never. Stop. Innovating.`))}
64
+ `);
65
+ }
66
+
67
+ // standardize merlin statements visually
68
+ function merlinSays(text) {
69
+ return `${_picocolors.default.yellow(_picocolors.default.bgBlack(` 🧙 Merlin: `))} ${_picocolors.default.bgBlack(_picocolors.default.green(` ${text} `))}`;
70
+ }
@@ -12,7 +12,6 @@ var path = _interopRequireWildcard(require("node:path"));
12
12
  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); }
13
13
  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; }
14
14
  const SITE_FILE_NAME = exports.SITE_FILE_NAME = "site.json";
15
-
16
15
  /**
17
16
  * Helper to convert dash to camel; important when reading attributes.
18
17
  */
@@ -0,0 +1 @@
1
+ !node_modules/
@@ -0,0 +1,17 @@
1
+ language: node_js
2
+ dist: trusty
3
+ sudo: required
4
+ addons:
5
+ firefox: "latest"
6
+ apt:
7
+ sources:
8
+ - google-chrome
9
+ packages:
10
+ - google-chrome-stable
11
+ node_js: stable
12
+ before_install:
13
+ - npm install -g web-component-tester
14
+ install:
15
+ - npm install
16
+ script:
17
+ - xvfb-run npm run test
@@ -15,12 +15,13 @@ DDD + Lit web component based on OpenWC toolchain. This is intended to provide t
15
15
  - `npm run release` - this will build your code, update the version, and publish it to npm for others to use
16
16
 
17
17
  ## Working with your web component
18
- - edit `/src/<%= name %>.js`
18
+ - edit `./<%= name %>.js`
19
19
  - edit your 'demo' by modifying `./index.html`
20
20
  - add dependencies using `npm install --save @whatever/repo` or editing `./package.json` directly
21
21
  - if you must reference additional non-JS files, ensure you use the `new URL('./my-file.jpg', import.meta.url).href` syntax so that it builds correctly
22
- - if you add additional `.js` files / web components then place them under `/src/`
22
+ - if you add additional `.js` files / web components then place them under `/lib/`
23
23
  - to improve HAX wiring edit file in `/lib/<%= name %>.haxProperties.json`
24
+ - for i18n / internationalization efforts, see associated language `.json` files in `/locales/` as well as `/lib/` for haxProperties related translation examples.
24
25
 
25
26
  ## Recommended setup
26
27
  - Load VS code in 1 window to project root
@@ -11,7 +11,6 @@
11
11
  :root, html, body {
12
12
  margin: 0;
13
13
  padding: 0;
14
- background-color: var(--ddd-accent-1);
15
14
  }
16
15
  #demo {
17
16
  margin: var(--ddd-spacing-2);
@@ -44,16 +43,18 @@
44
43
  <h2>Property usage</h2>
45
44
  <<%= name %> id="example" title="Sample property title"></<%= name %>>
46
45
  </div>
47
- <script type="module" src="./src/<%= name %>.js"></script>
46
+ <script type="module" src="./<%= name %>.js"></script>
48
47
 
49
48
  <!-- Take HAX, the Web and you further down the rabbit hole -->
50
49
  <style>
51
50
  #follow-the-white-rabbit {
52
51
  margin: var(--ddd-spacing-4) auto 64px 16px;
53
52
  background-color: var(--ddd-accent-4);
53
+ color: black;
54
54
  }
55
55
  #follow-the-white-rabbit[open] summary {
56
56
  background-color: var(--ddd-accent-4) !important;
57
+ color: black;
57
58
  }
58
59
  #follow-the-white-rabbit[open] .content {
59
60
  padding: 0 var(--ddd-spacing-4);
@@ -98,7 +99,7 @@
98
99
  Below are links to help on your journey. Good luck, we need you!
99
100
  </p>
100
101
  <ul>
101
- <li><a href="https://oer.hax.psu.edu/bto108/sites/haxcellence/documentation/ddd" target="_blank">🧑‍🎨 Learn DDD HAX Design system</a></li>
102
+ <li><a href="https://haxtheweb.org/documentation/ddd" target="_blank">🧑‍🎨 Learn DDD HAX Design system</a></li>
102
103
  <li><a href="https://lit.dev/playground/" target="_blank" rel="nofollow">🔥 Learn Lit</a></li>
103
104
  <li><a href="https://hax.psu.edu" target="_blank">🧙 HAX The Web @ Penn State</a></li>
104
105
  </ul>
@@ -0,0 +1,16 @@
1
+ {
2
+ "settings": {
3
+ "configure": [
4
+ {
5
+ "title": "عنوان"
6
+ }
7
+ ]
8
+ },
9
+ "demoSchema": [
10
+ {
11
+ "properties": {
12
+ "title": "قيمة مخصصة"
13
+ }
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "title": "عنوان"
3
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "settings": {
3
+ "configure": [
4
+ {
5
+ "title": "Título"
6
+ }
7
+ ]
8
+ },
9
+ "demoSchema": [
10
+ {
11
+ "properties": {
12
+ "title": "Valor personalizado"
13
+ }
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "title": "título"
3
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "settings": {
3
+ "configure": [
4
+ {
5
+ "title": "शीर्षक"
6
+ }
7
+ ]
8
+ },
9
+ "demoSchema": [
10
+ {
11
+ "properties": {
12
+ "title": "कस्टम मूल्य"
13
+ }
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "title": "शीर्षक"
3
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "settings": {
3
+ "configure": [
4
+ {
5
+ "title": "标题"
6
+ }
7
+ ]
8
+ },
9
+ "demoSchema": [
10
+ {
11
+ "properties": {
12
+ "title": "定制值"
13
+ }
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "title": "标题"
3
+ }
@@ -1,26 +1,35 @@
1
1
  {
2
- "name": "<%= name %>",
2
+ "name": "<%= org %><%= name %>",
3
+ "version": "0.0.0",
3
4
  "description": "Webcomponent <%= name %> following hax / open-wc recommendations",
4
5
  "license": "Apache-2.0",
5
- "author": "<%= author %>",
6
- "version": "0.0.0",
6
+ "author": {
7
+ "name": "<%= author %>"
8
+ },
9
+ "keywords": [
10
+ "webcomponents",
11
+ "lit",
12
+ "haxtheweb"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "<%= githubLink %>"
17
+ },
7
18
  "type": "module",
19
+ "main": "<%= name %>.js",
20
+ "module": "<%= name %>.js",
8
21
  "scripts": {
9
22
  "start": "web-dev-server",
10
23
  "build": "rimraf public && rollup -c rollup.config.js && npm run analyze",
11
24
  "analyze": "cem analyze --litelement --exclude public",
12
- "release": "npm run build && commit-and-tag-version && git push --follow-tags origin main && npm publish"
25
+ "release": "npm run build && commit-and-tag-version && git push --follow-tags origin main && npm publish",
26
+ "test": "web-test-runner test/**/*.test.js --coverage --node-resolve",
27
+ "test:watch": "web-test-runner test/**/*.test.js --node-resolve --watch"
13
28
  },
14
- "keywords": [
15
- "haxtheweb",
16
- "webcomponents",
17
- "lit",
18
- "generator",
19
- "starter-app"
20
- ],
21
29
  "dependencies": {
22
- "lit": "^3.1.4",
23
- "@haxtheweb/d-d-d": "^<%= version %>"
30
+ "lit": "^3.2.0",
31
+ "@haxtheweb/d-d-d": "^<%= version %>",
32
+ "@haxtheweb/i18n-manager": "^<%= version %>"
24
33
  },
25
34
  "devDependencies": {
26
35
  "@babel/preset-env": "^7.16.4",
@@ -29,7 +38,9 @@
29
38
  "@rollup/plugin-babel": "^6.0.4",
30
39
  "@rollup/plugin-node-resolve": "^15.2.3",
31
40
  "@rollup/plugin-terser": "^0.4.4",
32
- "@web/dev-server": "^0.4.5",
41
+ "@open-wc/testing": "^4.0.0",
42
+ "@web/dev-server": "^0.4.6",
43
+ "@web/test-runner": "^0.19.0",
33
44
  "@web/rollup-plugin-html": "^2.3.0",
34
45
  "@web/rollup-plugin-import-meta-assets": "^2.2.1",
35
46
  "babel-plugin-template-html-minifier": "^4.1.0",
@@ -38,5 +49,12 @@
38
49
  "rimraf": "^5.0.7",
39
50
  "commit-and-tag-version": "^12.4.1"
40
51
  },
52
+ "private": false,
53
+ "publishConfig": {
54
+ "access": "public"
55
+ },
56
+ "hax": {
57
+ "cli": true
58
+ },
41
59
  "customElements": "custom-elements.json"
42
60
  }
@@ -0,0 +1,21 @@
1
+ import { html, fixture, expect } from '@open-wc/testing';
2
+ import "../<%= name %>.js";
3
+
4
+ describe("<%= className %> test", () => {
5
+ let element;
6
+ beforeEach(async () => {
7
+ element = await fixture(html`
8
+ <<%= name %>
9
+ title="title"
10
+ ></<%= name %>>
11
+ `);
12
+ });
13
+
14
+ it("basic will it blend", async () => {
15
+ expect(element).to.exist;
16
+ });
17
+
18
+ it("passes the a11y audit", async () => {
19
+ await expect(element).shadowDom.to.be.accessible();
20
+ });
21
+ });
@@ -6,6 +6,8 @@ const hmr = process.argv.includes('--hmr');
6
6
  export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
7
7
  open: '/',
8
8
  watch: !hmr,
9
+ https: true,
10
+ dedupe: true,
9
11
  /** Resolve bare module imports */
10
12
  nodeResolve: {
11
13
  exportConditions: ['browser', 'development'],
@@ -1,7 +1,18 @@
1
+ /**
2
+ * Copyright <%= year %> <%= author %>
3
+ * @license Apache-2.0, see LICENSE for full text.
4
+ */
1
5
  import { LitElement, html, css } from "lit";
2
6
  import { DDDSuper } from "@haxtheweb/d-d-d/d-d-d.js";
7
+ import { I18NMixin } from "@haxtheweb/i18n-manager/lib/I18NMixin.js";
3
8
 
4
- export class <%= className %> extends DDDSuper(LitElement) {
9
+ /**
10
+ * `<%= name %>`
11
+ *
12
+ * @demo index.html
13
+ * @element <%= name %>
14
+ */
15
+ export class <%= className %> extends DDDSuper(I18NMixin(LitElement)) {
5
16
 
6
17
  static get tag() {
7
18
  return "<%= name %>";
@@ -10,14 +21,29 @@ export class <%= className %> extends DDDSuper(LitElement) {
10
21
  constructor() {
11
22
  super();
12
23
  this.title = "";
24
+ this.t = this.t || {};
25
+ this.t = {
26
+ ...this.t,
27
+ title: "Title",
28
+ };
29
+ this.registerLocalization({
30
+ context: this,
31
+ localesPath:
32
+ new URL("./locales/<%= name %>.ar.json", import.meta.url).href +
33
+ "/../",
34
+ locales: ["ar", "es", "hi", "zh"],
35
+ });
13
36
  }
14
37
 
38
+ // Lit reactive properties
15
39
  static get properties() {
16
40
  return {
41
+ ...super.properties,
17
42
  title: { type: String },
18
43
  };
19
44
  }
20
45
 
46
+ // Lit scoped styles
21
47
  static get styles() {
22
48
  return [super.styles,
23
49
  css`
@@ -26,23 +52,22 @@ export class <%= className %> extends DDDSuper(LitElement) {
26
52
  color: var(--ddd-theme-primary);
27
53
  background-color: var(--ddd-theme-accent);
28
54
  font-family: var(--ddd-font-navigation);
29
- font-size: var(--<%= name %>-font-size, var(--ddd-font-size-s));
30
55
  }
31
56
  .wrapper {
32
57
  margin: var(--ddd-spacing-2);
33
58
  padding: var(--ddd-spacing-4);
34
59
  }
35
- div {
36
- padding: 0;
37
- margin: 0;
60
+ h3 span {
61
+ font-size: var(--<%= name %>-label-font-size, var(--ddd-font-size-s));
38
62
  }
39
63
  `];
40
64
  }
41
65
 
66
+ // Lit render the HTML
42
67
  render() {
43
68
  return html`
44
69
  <div class="wrapper">
45
- <div>${this.title}</div>
70
+ <h3><span>${this.t.title}:</span> ${this.title}</h3>
46
71
  <slot></slot>
47
72
  </div>`;
48
73
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haxtheweb/create",
3
- "version": "9.0.5",
3
+ "version": "9.0.7",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -21,7 +21,8 @@
21
21
  "scripts": {
22
22
  "build": "rm -rf dist && babel src --out-dir dist --copy-files --include-dotfiles && chmod 774 dist/create.js",
23
23
  "start": "npm run build && node ./dist/create.js && chmod 774 dist/create.js",
24
- "release": "npm run build && commit-and-tag-version && git push --follow-tags origin main && npm publish"
24
+ "release": "npm run build && commit-and-tag-version && git push --follow-tags origin main && npm publish",
25
+ "haxcms-nodejs-cli": "./node_modules/.bin/haxcms-nodejs-cli"
25
26
  },
26
27
  "bin": {
27
28
  "create-haxtheweb": "./dist/create.js",
@@ -31,22 +32,18 @@
31
32
  "dist"
32
33
  ],
33
34
  "keywords": [
34
- "haxtheweb",
35
- "haxcms",
36
- "haxsite",
37
- "htw",
38
35
  "webcomponents",
36
+ "html",
39
37
  "lit",
40
- "cms",
41
- "generator",
42
- "starter-app"
38
+ "haxtheweb"
43
39
  ],
44
40
  "dependencies": {
45
41
  "@clack/core": "0.3.4",
46
42
  "@clack/prompts": "0.7.0",
47
- "@haxtheweb/haxcms-nodejs": "^9.0.5",
43
+ "@haxtheweb/haxcms-nodejs": "^9.0.11",
48
44
  "ejs": "3.1.10",
49
- "picocolors": "1.0.1"
45
+ "picocolors": "1.0.1",
46
+ "commander": "12.1.0"
50
47
  },
51
48
  "devDependencies": {
52
49
  "@babel/cli": "^7.24.6",
File without changes