create-template-project 1.7.2 → 1.9.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.
@@ -25,11 +25,11 @@
25
25
  "description": "A tiny JavaScript debugging utility modelled after Node.js core debugging technique."
26
26
  },
27
27
  "@commitlint/cli": {
28
- "version": "21.2.1",
28
+ "version": "21.2.2",
29
29
  "description": "Lint commit messages to ensure they follow conventional commits."
30
30
  },
31
31
  "@commitlint/config-conventional": {
32
- "version": "21.2.0",
32
+ "version": "21.2.2",
33
33
  "description": "Shareable commitlint config enforcing conventional commits."
34
34
  },
35
35
  "@types/debug": {
@@ -45,11 +45,11 @@
45
45
  "description": "V8 coverage provider for Vitest."
46
46
  },
47
47
  "conventional-changelog": {
48
- "version": "8.1.1",
48
+ "version": "8.1.3",
49
49
  "description": "Generate a changelog from git metadata."
50
50
  },
51
51
  "conventional-changelog-angular": {
52
- "version": "9.2.1",
52
+ "version": "9.3.0",
53
53
  "description": "Angular preset for conventional-changelog."
54
54
  },
55
55
  "husky": {
@@ -57,7 +57,7 @@
57
57
  "description": "Modern native git hooks made easy."
58
58
  },
59
59
  "oxlint": {
60
- "version": "1.77.0",
60
+ "version": "1.78.0",
61
61
  "description": "A JavaScript linter written in Rust."
62
62
  },
63
63
  "oxlint-tsgolint": {
@@ -65,12 +65,13 @@
65
65
  "description": "TypeScript-specific rules for oxlint."
66
66
  },
67
67
  "oxfmt": {
68
- "version": "0.62.0",
68
+ "version": "0.63.0",
69
69
  "description": "High performance JavaScript / TypeScript formatter."
70
70
  },
71
71
  "typescript": {
72
72
  "version": "6.0.3",
73
- "description": "A superset of JavaScript that compiles to clean JavaScript output."
73
+ "description": "A superset of JavaScript that compiles to clean JavaScript output.",
74
+ "fixed": true
74
75
  },
75
76
  "vitest": {
76
77
  "version": "4.1.10",
@@ -157,7 +158,7 @@
157
158
  "description": "Declarative routing for React web applications."
158
159
  },
159
160
  "release-it": {
160
- "version": "21.0.1",
161
+ "version": "21.0.2",
161
162
  "description": "Interactive release-tool for Git repositories."
162
163
  },
163
164
  "cors": {
@@ -169,7 +170,7 @@
169
170
  "description": "TypeScript definitions for cors."
170
171
  },
171
172
  "eslint-plugin-regexp": {
172
- "version": "3.1.1",
173
+ "version": "3.2.0",
173
174
  "description": "ESLint plugin for finding regexp mistakes and style guide violations."
174
175
  },
175
176
  "vitest-browser-react": {
@@ -40,6 +40,7 @@ export const linter = defineConfig({
40
40
  },
41
41
  rules: {
42
42
  ...regexpPluginRules,
43
+ 'eslint/capitalized-comments': 'off', // TODO: consider enabling
43
44
  'eslint/complexity': 'off', // TODO: consider enabling
44
45
  'eslint/curly': ['error', 'all'],
45
46
  'eslint/id-length': 'off',
@@ -49,7 +50,6 @@ export const linter = defineConfig({
49
50
  'eslint/max-lines-per-function': 'off', // TODO: consider enabling
50
51
  'eslint/max-params': 'off', // TODO: consider enabling
51
52
  'eslint/max-statements': 'off', // TODO: consider enabling
52
- 'eslint/capitalized-comments': 'off', // TODO: consider enabling
53
53
  'eslint/no-await-in-loop': 'warn',
54
54
  'eslint/no-console': 'off',
55
55
  'eslint/no-continue': 'off',
@@ -60,6 +60,7 @@ export const linter = defineConfig({
60
60
  'eslint/no-warning-comments': 'off',
61
61
  'eslint/no-undefined': 'off', // TODO: consider enabling
62
62
  'eslint/no-plusplus': 'off',
63
+ 'eslint/one-var': 'off',
63
64
  'eslint/sort-imports': 'off',
64
65
  'eslint/sort-keys': 'off',
65
66
  'eslint/no-ternary': 'off',
@@ -85,62 +86,6 @@ export const linter = defineConfig({
85
86
  'import/no-unassigned-import': ['error', {allow: ['**/*.css']}],
86
87
  'import/prefer-default-export': 'off',
87
88
  'import/no-default-export': 'off',
88
- 'jest/consistent-test-it': 'off',
89
- 'jest/expect-expect': 'off',
90
- 'jest/max-expects': 'off',
91
- 'jest/max-nested-describe': 'off',
92
- 'jest/no-alias-methods': 'off',
93
- 'jest/no-commented-out-tests': 'off',
94
- 'jest/no-conditional-expect': 'off',
95
- 'jest/no-conditional-in-test': 'off',
96
- 'jest/no-confusing-set-timeout': 'off',
97
- 'jest/no-deprecated-functions': 'off',
98
- 'jest/no-disabled-tests': 'off',
99
- 'jest/no-done-callback': 'off',
100
- 'jest/no-duplicate-hooks': 'off',
101
- 'jest/no-export': 'off',
102
- 'jest/no-focused-tests': 'off',
103
- 'jest/no-hooks': 'off',
104
- 'jest/no-identical-title': 'off',
105
- 'jest/no-interpolation-in-snapshots': 'off',
106
- 'jest/no-jasmine-globals': 'off',
107
- 'jest/no-large-snapshots': 'off',
108
- 'jest/no-mocks-import': 'off',
109
- 'jest/no-restricted-jest-methods': 'off',
110
- 'jest/no-restricted-matchers': 'off',
111
- 'jest/no-standalone-expect': 'off',
112
- 'jest/no-test-prefixes': 'off',
113
- 'jest/no-test-return-statement': 'off',
114
- 'jest/no-unneeded-async-expect-function': 'off',
115
- 'jest/no-untyped-mock-factory': 'off',
116
- 'jest/padding-around-test-blocks': 'off',
117
- 'jest/prefer-called-with': 'off',
118
- 'jest/prefer-comparison-matcher': 'off',
119
- 'jest/prefer-each': 'off',
120
- 'jest/prefer-ending-with-an-expect': 'off',
121
- 'jest/prefer-equality-matcher': 'off',
122
- 'jest/prefer-expect-assertions': 'off',
123
- 'jest/prefer-expect-resolves': 'off',
124
- 'jest/prefer-hooks-in-order': 'off',
125
- 'jest/prefer-hooks-on-top': 'off',
126
- 'jest/prefer-jest-mocked': 'off',
127
- 'jest/prefer-lowercase-title': 'off',
128
- 'jest/prefer-mock-promise-shorthand': 'off',
129
- 'jest/prefer-mock-return-shorthand': 'off',
130
- 'jest/prefer-spy-on': 'off',
131
- 'jest/prefer-strict-equal': 'off',
132
- 'jest/prefer-to-be': 'off',
133
- 'jest/prefer-to-contain': 'off',
134
- 'jest/prefer-to-have-been-called': 'off',
135
- 'jest/prefer-to-have-been-called-times': 'off',
136
- 'jest/prefer-to-have-length': 'off',
137
- 'jest/prefer-todo': 'off',
138
- 'jest/require-hook': 'off',
139
- 'jest/require-to-throw-message': 'off',
140
- 'jest/require-top-level-describe': 'off',
141
- 'jest/valid-describe-callback': 'off',
142
- 'jest/valid-expect': 'off',
143
- 'jest/valid-title': 'off',
144
89
  'jsdoc/require-param': 'error',
145
90
  'jsdoc/require-param-type': 'off',
146
91
  'jsdoc/require-returns': 'warn',
@@ -0,0 +1,39 @@
1
+ import {act, createRef, type ComponentRef} from 'react';
2
+ import {createRoot} from 'react-dom/client';
3
+ import {describe, expect, it, vi} from 'vitest';
4
+
5
+ import {DemoWidget} from './react.tsx';
6
+
7
+ describe('DemoWidget React wrapper', () => {
8
+ it('preserves mount options, updates mutable props, forwards refs, and cleans up', () => {
9
+ const host = document.createElement('div');
10
+ const firstRef = createRef<ComponentRef<typeof DemoWidget>>();
11
+ const secondRef = vi.fn<(value: ComponentRef<typeof DemoWidget> | null) => void>();
12
+ const root = createRoot(host);
13
+
14
+ act(() => {
15
+ root.render(<DemoWidget ref={firstRef} title="Initial title" message="Initial message" />);
16
+ });
17
+
18
+ const instance = firstRef.current;
19
+ expect(instance).not.toBeNull();
20
+ expect(host.querySelector('.widget__title')?.textContent).toBe('Initial title');
21
+ expect(host.querySelector('.widget__message')?.textContent).toBe('Initial message');
22
+
23
+ act(() => {
24
+ root.render(<DemoWidget ref={secondRef} title="Ignored title" message="Updated message" />);
25
+ });
26
+
27
+ expect(firstRef.current).toBeNull();
28
+ expect(secondRef).toHaveBeenLastCalledWith(instance);
29
+ expect(host.querySelector('.widget__title')?.textContent).toBe('Initial title');
30
+ expect(host.querySelector('.widget__message')?.textContent).toBe('Updated message');
31
+
32
+ act(() => {
33
+ root.unmount();
34
+ });
35
+
36
+ expect(secondRef).toHaveBeenLastCalledWith(null);
37
+ expect(host.children).toHaveLength(0);
38
+ });
39
+ });
@@ -17,31 +17,33 @@ const setForwardedRef = (ref: ForwardedRef<DemoWidgetInstance>, value: DemoWidge
17
17
  };
18
18
 
19
19
  export const DemoWidget = forwardRef<DemoWidgetInstance, DemoWidgetReactProps>((props, ref): ReactElement => {
20
- const {message, ...mountOptions} = props;
20
+ const {message} = props;
21
+ const initialOptionsRef = useRef<DemoWidgetOptions>(props);
21
22
  const hostRef = useRef<HTMLDivElement | null>(null);
22
23
  const instanceRef = useRef<DemoWidgetInstance | null>(null);
23
24
 
24
25
  useEffect(() => {
25
26
  const host = hostRef.current;
26
27
  if (host === null) {
27
- return (): void => {
28
- setForwardedRef(ref, null);
29
- };
28
+ throw new Error('Widget host was not mounted.');
30
29
  }
31
30
 
32
- const instance = new NativeDemoWidget(host, {...mountOptions, ...(message === undefined ? {} : {message})});
31
+ const instance = new NativeDemoWidget(host, initialOptionsRef.current);
33
32
  instanceRef.current = instance;
34
- setForwardedRef(ref, instance);
35
33
 
36
34
  return (): void => {
37
35
  instanceRef.current = null;
38
- setForwardedRef(ref, null);
39
36
  instance.destroy();
40
37
  };
41
- // Mount-only options are intentionally captured once. Mutable props are synced below through native setters.
42
- // oxlint-disable-next-line react-hooks/exhaustive-deps
43
38
  }, []);
44
39
 
40
+ useEffect(() => {
41
+ setForwardedRef(ref, instanceRef.current);
42
+ return (): void => {
43
+ setForwardedRef(ref, null);
44
+ };
45
+ }, [ref]);
46
+
45
47
  useEffect(() => {
46
48
  if (message !== undefined) {
47
49
  instanceRef.current?.setMessage(message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-template-project",
3
- "version": "1.7.2",
3
+ "version": "1.9.0",
4
4
  "private": false,
5
5
  "description": "An ultra-modular, type-safe Node.js CLI tool used to scaffold new project templates (CLI, Webpage, Web Widget, Webapp, Fullstack) with best-practice configurations pre-installed.",
6
6
  "keywords": [
@@ -60,18 +60,18 @@
60
60
  "zod": "4.4.3"
61
61
  },
62
62
  "devDependencies": {
63
- "@commitlint/cli": "21.2.1",
64
- "@commitlint/config-conventional": "21.2.0",
63
+ "@commitlint/cli": "21.2.2",
64
+ "@commitlint/config-conventional": "21.2.2",
65
65
  "@types/cli-progress": "3.11.6",
66
66
  "@types/debug": "4.1.13",
67
67
  "@types/node": "26.2.0",
68
68
  "@vitest/coverage-v8": "4.1.10",
69
- "conventional-changelog": "8.1.1",
70
- "conventional-changelog-angular": "9.2.1",
71
- "eslint-plugin-regexp": "3.1.1",
69
+ "conventional-changelog": "8.1.3",
70
+ "conventional-changelog-angular": "9.3.0",
71
+ "eslint-plugin-regexp": "3.2.0",
72
72
  "husky": "9.1.7",
73
- "oxfmt": "0.62.0",
74
- "oxlint": "1.77.0",
73
+ "oxfmt": "0.63.0",
74
+ "oxlint": "1.78.0",
75
75
  "oxlint-tsgolint": "7.0.2001",
76
76
  "release-it": "21.0.2",
77
77
  "rimraf": "6.1.3",