@nutin/cli 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+
3
+ ## V1.0.1
4
+
5
+ - Fixed typo issue when using i18n feature
6
+
7
+ ## V1.0.2
8
+
9
+ - Partially fixed `npm run dev` script when using internal templates. *Page still needs to be reload manually from time to time.*
10
+
11
+ ## V1.1.0
12
+
13
+ - Added index access in CatalogConfig. Use with `config.index`.
14
+ ```typescript
15
+ interface CatalogItemBase {
16
+ idx: number;
17
+ }
18
+ type CatalogItemObject<T extends object> = T & CatalogItemBase;
19
+ interface CatalogItemPrimitive extends CatalogItemBase {
20
+ value: string | number | boolean | null | undefined;
21
+ }
22
+
23
+ // type safety
24
+ type CatalogItemConfig<T = any> =
25
+ T extends object ? CatalogItemObject<T> : CatalogItemPrimitive;
26
+ ```
27
+
28
+ **Notes:** *Primitive data arrays (string, number, etc) needs to be accessed with `config.value`.*
@@ -54,7 +54,9 @@ export class ProjectGenerator {
54
54
  await this.processFeatureTemplates(projectPath, context);
55
55
  }
56
56
 
57
- buildContext(answers) {
57
+ buildContext(answers) {
58
+ const version = '1.1.0';
59
+
58
60
  return {
59
61
  projectName: answers.projectName,
60
62
  description: answers.description || `A modern web application`,
@@ -68,7 +70,8 @@ export class ProjectGenerator {
68
70
  hasFeatures: answers.template || answers.stylinNutin || answers.i18n || answers.transition || answers.testinNutin,
69
71
 
70
72
  year: new Date().getFullYear(),
71
- packageManager: answers.packageManager || 'npm'
73
+ packageManager: answers.packageManager || 'npm',
74
+ version: version
72
75
  };
73
76
  }
74
77
 
@@ -52,7 +52,10 @@ export async function generatePackageJson(projectPath, answers) {
52
52
  ...baseScripts,
53
53
  "test": "node test/runner.js",
54
54
  "test--rebuild": "npm run build && npm run test",
55
- "test:watch": "npm run build && node test/watch-tests.js"
55
+ "test:watch": "npm run build && node test/watch-tests.js",
56
+ "serve": "npm run build && npm run serve:only",
57
+ "serve:only": "live-server dist/src --port=9090 --entry-file=index.html --open",
58
+ "dev": "concurrently \"node tools/watcher.js\" \"npm run build && npm run serve:only > /dev/null 2>&1\""
56
59
  }
57
60
  : baseScripts;
58
61
 
@@ -61,19 +64,12 @@ export async function generatePackageJson(projectPath, answers) {
61
64
  ...scripts,
62
65
  "build:clear": "rm -rf dist/src/* dist-build",
63
66
  "build:finalize": "mkdir -p dist && mv dist-build/src dist/ && rm -rf dist-build",
64
- "build": "npm run build:clear && npm run build:ts && npm run build-static && npm run build:finalize",
65
- "serve:only": "live-server dist/src --port=9090 --entry-file=index.html --open",
66
- "serve": "npm run build && npm run serve:only",
67
- "dev": "concurrently \"node tools/watcher.js\" \"npm run build && npm run serve:only > /dev/null 2>&1\"",
67
+ "build": "npm run build:clear && npm run build:ts && npm run build-static && npm run build:finalize"
68
68
  }
69
69
  : {
70
70
  ...scripts,
71
71
  "build:clear": "rm -rf dist",
72
- "build": "npm run build:clear && npm run build:ts && npm run build-static",
73
- "dev": "concurrently \"npm run watch\" \"npm run serve\"",
74
- "watch:ts": "tsc --watch",
75
- "watch:sass": "sass --watch src/styles:dist/css",
76
- "watch": "concurrently \"npm:watch:*\""
72
+ "build": "npm run build:clear && npm run build:ts && npm run build-static"
77
73
  };
78
74
 
79
75
  const packageJson = {
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@nutin/cli",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "A lightweight, highly tweakable frontend toolkit, crafted for building lean, dynamic single-page applications without the complexity of full-scale frameworks.",
5
+ "preferGlobal": true,
5
6
  "main": "lib/index.mjs",
6
7
  "bin": {
7
8
  "create-nutin-app": "./bin/create-app.mjs",
@@ -23,7 +23,7 @@ const template = `{{#if template}}__TEMPLATE_PLACEHOLDER__{{else}}<div
23
23
  {{else}}
24
24
  style="font-style:italic;font-size:0.75rem;"
25
25
  {{/if}}
26
- >nutin v1.0.0</span>
26
+ >nutin v{{version}}</span>
27
27
  <img src="/assets/images/logo-trans.avif" width=250 height=250 alt="nutin's logo. A frame opened on the top left through which a plant grows.">
28
28
  <div
29
29
  {{#if i18n}}
@@ -8,6 +8,19 @@ export interface CatalogConfig {
8
8
  component: new (el: HTMLElement, data: any) => BaseComponent;
9
9
  };
10
10
 
11
+ export interface CatalogItemBase {
12
+ idx: number;
13
+ }
14
+
15
+ export type CatalogItemObject<T extends object> = T & CatalogItemBase;
16
+
17
+ export interface CatalogItemPrimitive extends CatalogItemBase {
18
+ value: string | number | boolean | null | undefined;
19
+ }
20
+
21
+ export type CatalogItemConfig<T = any> =
22
+ T extends object ? CatalogItemObject<T> : CatalogItemPrimitive;
23
+
11
24
  /**
12
25
  * ```typescript
13
26
  interface CatalogConfig {
@@ -17,6 +30,9 @@ interface CatalogConfig {
17
30
  selector: string;
18
31
  component: new (el: HTMLElement, data: any) => BaseComponent;
19
32
  };
33
+
34
+ type CatalogItemConfig<T = any> =
35
+ T extends object ? CatalogItemObject<T> : CatalogItemPrimitive;
20
36
  ```
21
37
  */
22
38
  export class CatalogHelper {
@@ -40,14 +56,21 @@ export class CatalogHelper {
40
56
  private static createElements(idx: number, config: CatalogConfig, container: HTMLElement) {
41
57
  const el = document.createElement(config.elementTag || 'div');
42
58
  el.setAttribute('data-component', `${config.elementName}-${idx}`);
59
+ el.dataset.index = String(idx);
43
60
  container?.appendChild(el);
44
61
  }
45
62
 
46
63
  private static pushConfig(idx: number, componentConfigs: ComponentConfig[], config: CatalogConfig) {
64
+ const item = config.array[idx];
65
+
66
+ const configWithIndex: CatalogItemConfig = (item && typeof item === 'object')
67
+ ? { ...(item as object), index: idx }
68
+ : { value: item, index: idx };
69
+
47
70
  componentConfigs.push(
48
71
  {
49
72
  selector: `${config.elementName}-${idx}`,
50
- factory: (el) => new config.component(el, config.array[idx])
73
+ factory: (el) => new config.component(el, configWithIndex)
51
74
  },
52
75
  )
53
76
  }
@@ -0,0 +1,44 @@
1
+ import chokidar from 'chokidar';
2
+ import { exec } from 'child_process';
3
+ import path from 'path';
4
+ import { print } from './utils/index.js'
5
+
6
+ const watcher = chokidar.watch(['src'], {
7
+ ignored: /(^|[/\\])\../,
8
+ persistent: true,
9
+ });
10
+
11
+ let isBuilding = false;
12
+
13
+ let buildTimeout = null;
14
+
15
+ watcher.on('change', (filePath) => {
16
+ if (buildTimeout) {
17
+ clearTimeout(buildTimeout);
18
+ }
19
+
20
+ buildTimeout = setTimeout(() => {
21
+ if (isBuilding) return;
22
+ isBuilding = true;
23
+
24
+ console.clear();
25
+ print.boldInfo(`\nšŸ”„ File changed: ${path.relative(process.cwd(), filePath)}\n`);
26
+ print.info('\nRebuilding...');
27
+
28
+ const command = {{#if template}}'npm run build'{{else}}filePath.includes('.scss') ? 'npm run build-static' : 'npm run build'{{/if}};
29
+
30
+ exec(command, (err, stdout, stderr) => {
31
+ if (stdout) process.stdout.write(stdout);
32
+ if (stderr) process.stderr.write(stderr);
33
+
34
+ print.boldSuccess('\nāœ… Build completed!');
35
+ print.boldHead('\nWaiting for changes...\n');
36
+
37
+ isBuilding = false;
38
+ });
39
+ }, 100);
40
+ });
41
+
42
+ watcher.on('ready', () => {
43
+ print.boldHead('\nšŸ‘€ Watching for changes...\n');
44
+ });
@@ -21,7 +21,7 @@
21
21
  {{else}}
22
22
  style="font-style:italic;font-size:0.75rem;"
23
23
  {{/if}}
24
- >nutin v1.0.0</span>
24
+ >nutin v{{version}}</span>
25
25
  <img src="/assets/images/logo-trans.avif" width=250 height=250 alt="nutin's logo. A frame opened on the top left through which a plant grows.">
26
26
  <div
27
27
  {{#if i18n}}
@@ -1,27 +0,0 @@
1
- import chokidar from 'chokidar';
2
- import { exec } from 'child_process';
3
- import path from 'path';
4
- import { print } from './utils/index.js'
5
-
6
- const watcher = chokidar.watch(['src'], {
7
- ignored: /(^|[/\\])\../,
8
- persistent: true,
9
- });
10
-
11
- let isBuilding = false;
12
-
13
- watcher.on('change', (filePath) => {
14
- if (isBuilding) return;
15
- isBuilding = true;
16
-
17
- console.clear();
18
- print.boldInfo(`\nšŸ”„ File changed: ${path.relative(process.cwd(), filePath)}\n`);
19
- print.info('\nRebuilding...')
20
-
21
- exec('npm run build', (err, stdout, stderr) => {
22
- if (stderr) process.stderr.write(stderr);
23
- print.boldHead('\nWaiting for changes...');
24
- });
25
-
26
- isBuilding = false;
27
- });