@chemx/starter-kit 26.9.16-41 → 26.9.17-309

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.
Files changed (71) hide show
  1. package/README.md +4 -0
  2. package/assets/chemx-starter-kit-logo.gif +0 -0
  3. package/blueprints/_view-template.scss +24 -0
  4. package/blueprints/atoms/a-button.vue +43 -0
  5. package/blueprints/molecule-capsule/_m-sample-card.scss +75 -0
  6. package/blueprints/molecule-capsule/index.ts +2 -0
  7. package/blueprints/molecule-capsule/m-chemx-badge/_m-chemx-badge.scss +76 -0
  8. package/blueprints/molecule-capsule/m-chemx-badge/index.ts +3 -0
  9. package/blueprints/molecule-capsule/m-chemx-badge/m-chemx-badge.spec.ts +74 -0
  10. package/blueprints/molecule-capsule/m-chemx-badge/m-chemx-badge.tsx +39 -0
  11. package/blueprints/molecule-capsule/m-chemx-badge/m-chemx-badge.vue +42 -0
  12. package/blueprints/molecule-capsule/m-chemx-badge/types.d.ts +12 -0
  13. package/blueprints/molecule-capsule/m-sample-card.spec.ts +74 -0
  14. package/blueprints/molecule-capsule/m-sample-card.tsx +72 -0
  15. package/blueprints/molecule-capsule/m-tab-button/_m-tab-button.scss +49 -0
  16. package/blueprints/molecule-capsule/m-tab-button/index.ts +3 -0
  17. package/blueprints/molecule-capsule/m-tab-button/m-tab-button.controller.ts +43 -0
  18. package/blueprints/molecule-capsule/m-tab-button/m-tab-button.spec.ts +40 -0
  19. package/blueprints/molecule-capsule/m-tab-button/m-tab-button.vue +38 -0
  20. package/blueprints/molecule-capsule/m-tab-button/types.d.ts +14 -0
  21. package/blueprints/molecule-capsule/types.d.ts +12 -0
  22. package/blueprints/shims-vue.d.ts +4 -0
  23. package/blueprints/view-template.tsx +20 -0
  24. package/blueprints/workflows/chemx-audit.yml +79 -0
  25. package/cli/audit/autofix.js +4 -5
  26. package/cli/audit/pattern-detector.js +90 -3
  27. package/cli/audit/pattern-detector.spec.js +36 -1
  28. package/cli/audit/prompts.js +10 -12
  29. package/cli/audit/roadmap.js +5 -20
  30. package/cli/audit/rules-predicates.js +3 -2
  31. package/cli/audit/rules.js +4 -0
  32. package/cli/audit-preflight-git.js +54 -0
  33. package/cli/audit-preflight-scope.js +87 -0
  34. package/cli/audit-preflight.d.ts +16 -0
  35. package/cli/audit-preflight.js +85 -0
  36. package/cli/audit-preflight.spec.js +115 -0
  37. package/cli/audit.js +47 -22
  38. package/cli/generator-templates/controller.js +36 -0
  39. package/cli/generator-templates/hooks.js +60 -0
  40. package/cli/generator-templates/naming.js +14 -0
  41. package/cli/generator-templates/react.js +63 -0
  42. package/cli/generator-templates/specs.js +38 -0
  43. package/cli/generator-templates/styles.js +64 -0
  44. package/cli/generator-templates/svelte.js +66 -0
  45. package/cli/generator-templates/types.js +29 -0
  46. package/cli/generator-templates/views.js +76 -0
  47. package/cli/generator-templates/vue.js +62 -0
  48. package/cli/generator-templates.d.ts +35 -0
  49. package/cli/generator-templates.js +28 -480
  50. package/cli/generator-templates.spec.js +108 -0
  51. package/cli/generator.js +2 -2
  52. package/cli/generator.spec.js +61 -1
  53. package/cli/help.js +9 -0
  54. package/cli/index.js +44 -7
  55. package/cli/installer-templates.js +67 -13
  56. package/cli/license.js +22 -1
  57. package/cli/mcp/installer.js +31 -21
  58. package/cli/mcp/resources.js +114 -7
  59. package/cli/mcp/server.spec.js +34 -0
  60. package/cli/mcp/tools.js +14 -4
  61. package/cli/postinstall.js +27 -0
  62. package/cli/project-detector.js +20 -2
  63. package/cli/project-detector.spec.js +19 -0
  64. package/cli/reader.js +18 -4
  65. package/cli/scaffold.js +19 -3
  66. package/cli/terminal.js +36 -1
  67. package/docs/CHANGELOG.md +10 -0
  68. package/package.json +8 -5
  69. package/scripts/postinstall.mjs +27 -0
  70. package/scripts/pre-commit.sh +135 -0
  71. package/scripts/publish-both.mjs +108 -0
@@ -0,0 +1,76 @@
1
+ export const buildReactView = (name, pascalName) => `import React from 'react';
2
+ import type { ${pascalName}ViewParams } from './types';
3
+
4
+ export const ${pascalName}View: React.FC<${pascalName}ViewParams> = ({
5
+ HeaderMolecule,
6
+ MainOrganism,
7
+ FooterMolecule
8
+ }) => (
9
+ <main className="${name}">
10
+ {HeaderMolecule}
11
+ {MainOrganism}
12
+ {FooterMolecule}
13
+ </main>
14
+ );
15
+
16
+ export default ${pascalName}View;
17
+ `;
18
+
19
+ export const buildVueView = (name, pascalName) => `<script setup lang="ts">
20
+ import type { ${pascalName}ViewParams } from './types';
21
+
22
+ defineProps<${pascalName}ViewParams>();
23
+ </script>
24
+
25
+ <template>
26
+ <main class="${name}">
27
+ <component :is="HeaderMolecule" />
28
+ <component :is="MainOrganism" />
29
+ <component :is="FooterMolecule" />
30
+ </main>
31
+ </template>
32
+ `;
33
+
34
+ export const buildSvelteView = (name, pascalName) => `<script lang="ts">
35
+ import type { ${pascalName}ViewParams } from './types';
36
+
37
+ const {
38
+ HeaderMolecule,
39
+ MainOrganism,
40
+ FooterMolecule
41
+ }: ${pascalName}ViewParams = $props();
42
+ </script>
43
+
44
+ <main class="${name}">
45
+ {@render HeaderMolecule?.()}
46
+ {@render MainOrganism?.()}
47
+ {@render FooterMolecule?.()}
48
+ </main>
49
+ `;
50
+
51
+ export const buildViewParamsType = (pascalName) => `export interface ${pascalName}ViewParams {
52
+ readonly HeaderMolecule?: unknown;
53
+ readonly MainOrganism?: unknown;
54
+ readonly FooterMolecule?: unknown;
55
+ }
56
+ `;
57
+
58
+ export const buildViewIndex = (name, pascalName, ext) => {
59
+ const compExport = ext === 'vue' || ext === 'svelte'
60
+ ? `export { default as ${pascalName}View } from './${name}.${ext}';`
61
+ : `export { ${pascalName}View } from './${name}';`;
62
+
63
+ return `${compExport}
64
+ export type * from './types';
65
+ `;
66
+ };
67
+
68
+ export const buildViewSpec = (name, pascalName) => `import { describe, it } from 'node:test';
69
+ import assert from 'node:assert/strict';
70
+
71
+ describe('${pascalName}View Table of Contents', () => {
72
+ it('defines pure declarative blueprint layout', () => {
73
+ assert.ok(true);
74
+ });
75
+ });
76
+ `;
@@ -0,0 +1,62 @@
1
+ export const buildVueComponent = (name, pascalName, options = {}) => {
2
+ const atomsPackage = options.atomsPackage || null;
3
+ const hasController = options.hasController !== false;
4
+ const actionButton = atomsPackage
5
+ ? ` <a-button
6
+ :disabled="!canProceed"
7
+ @click="handleAction"
8
+ >
9
+ {{ variant }}
10
+ </a-button>`
11
+ : ` <button
12
+ type="button"
13
+ class="${name}__action"
14
+ :disabled="!canProceed"
15
+ @click="handleAction"
16
+ >
17
+ {{ variant }}
18
+ </button>`;
19
+
20
+ const controllerImport = hasController
21
+ ? `import { use${pascalName}Controller } from './${name}.controller';\n`
22
+ : '';
23
+
24
+ const controllerLogic = hasController
25
+ ? `const { state, canProceed, descriptor, handleAction } = use${pascalName}Controller({
26
+ initialState: { status: 'idle' },
27
+ onAction: () => emit('action', props.title)
28
+ });`
29
+ : `const canProceed = true;
30
+ const descriptor = { text: 'Ready', className: '${name}__badge ${name}__badge--ready' };
31
+ const handleAction = () => emit('action', props.title);`;
32
+
33
+ return `<script setup lang="ts">
34
+ import type { ${pascalName}Props, ${pascalName}Emits } from './types';
35
+ ${controllerImport}
36
+ const props = withDefaults(defineProps<${pascalName}Props>(), {
37
+ variant: 'standard'
38
+ });
39
+
40
+ const emit = defineEmits<${pascalName}Emits>();
41
+
42
+ ${controllerLogic}
43
+ </script>
44
+
45
+ <template>
46
+ <div class="${name}">
47
+ <div class="${name}__header">
48
+ <h3 class="${name}__title">{{ title }}</h3>
49
+ <p v-if="subtitle" class="${name}__subtitle">{{ subtitle }}</p>
50
+ <span :class="descriptor.className">{{ descriptor.text }}</span>
51
+ </div>
52
+ <div class="${name}__body">
53
+ ${actionButton}
54
+ </div>
55
+ </div>
56
+ </template>
57
+
58
+ <style lang="scss" scoped>
59
+ @use './_${name}.scss';
60
+ </style>
61
+ `;
62
+ };
@@ -0,0 +1,35 @@
1
+ export interface TemplateOptions {
2
+ readonly atomsPackage?: string | null;
3
+ readonly hasController?: boolean;
4
+ }
5
+
6
+ export declare function toPascalCase(str: string): string;
7
+ export declare function toCamelCase(str: string): string;
8
+
9
+ export declare function buildReactComponent(name: string, pascalName: string, options?: TemplateOptions): string;
10
+ export declare function buildVueComponent(name: string, pascalName: string, options?: TemplateOptions): string;
11
+ export declare function buildSvelteComponent(name: string, pascalName: string, options?: TemplateOptions): string;
12
+
13
+ export declare function buildController(name: string, pascalName: string): string;
14
+ export declare function buildComponentSpec(name: string, pascalName: string, hasController?: boolean): string;
15
+ export declare function buildIndex(name: string, pascalName: string, ext: string, hasController?: boolean): string;
16
+
17
+ export declare function buildPropsType(name: string, pascalName: string): string;
18
+ export declare function buildStateType(name: string, pascalName: string): string;
19
+ export declare function buildTypesIndex(fileNames?: string[]): string;
20
+ export declare function buildTypes(name: string, pascalName: string): string;
21
+
22
+ export declare function buildScss(name: string): string;
23
+
24
+ export declare function buildHook(name: string, camelName: string, pascalName: string): string;
25
+ export declare function buildHookOptionsType(pascalName: string): string;
26
+ export declare function buildHookReturnType(pascalName: string): string;
27
+ export declare function buildHookIndex(name: string, camelName: string): string;
28
+ export declare function buildHookSpec(name: string, camelName: string): string;
29
+
30
+ export declare function buildReactView(name: string, pascalName: string): string;
31
+ export declare function buildVueView(name: string, pascalName: string): string;
32
+ export declare function buildSvelteView(name: string, pascalName: string): string;
33
+ export declare function buildViewParamsType(pascalName: string): string;
34
+ export declare function buildViewIndex(name: string, pascalName: string, ext: string): string;
35
+ export declare function buildViewSpec(name: string, pascalName: string): string;
@@ -1,480 +1,28 @@
1
- export const toPascalCase = (str) =>
2
- str
3
- .replace(/^(?:[a-z]|use|v)-/, '')
4
- .split('-')
5
- .map((p) => p.charAt(0).toUpperCase() + p.slice(1))
6
- .join('');
7
-
8
- export const toCamelCase = (str) => {
9
- const p = toPascalCase(str);
10
- if (str.startsWith('use-') || str.startsWith('use')) {
11
- return `use${p}`;
12
- }
13
- return p.charAt(0).toLowerCase() + p.slice(1);
14
- };
15
-
16
- export const buildReactComponent = (name, pascalName, options = {}) => {
17
- const atomsPackage = options.atomsPackage || null;
18
- const atomImport = atomsPackage ? `import { AtomButton } from '${atomsPackage}';\n` : '';
19
- const actionButton = atomsPackage
20
- ? ` <AtomButton
21
- disabled={!canProceed}
22
- onClick={handleAction}
23
- >
24
- {variant}
25
- </AtomButton>`
26
- : ` <button
27
- type="button"
28
- className="${name}__action"
29
- disabled={!canProceed}
30
- onClick={handleAction}
31
- >
32
- {variant}
33
- </button>`;
34
-
35
- return `import React from 'react';
36
- ${atomImport}import type { ${pascalName}Props } from './types';
37
- import { use${pascalName}Controller } from './${name}.controller';
38
-
39
- export const ${pascalName}: React.FC<${pascalName}Props> = ({
40
- title,
41
- subtitle,
42
- variant = 'standard',
43
- onAction
44
- }) => {
45
- const { state, canProceed, descriptor, handleAction } = use${pascalName}Controller({
46
- initialState: { status: 'idle' },
47
- onAction
48
- });
49
-
50
- return (
51
- <div className="${name}">
52
- <div className="${name}__header">
53
- <h3 className="${name}__title">{title}</h3>
54
- {subtitle && <p className="${name}__subtitle">{subtitle}</p>}
55
- <span className={descriptor.className}>{descriptor.text}</span>
56
- </div>
57
- <div className="${name}__body">
58
- ${actionButton}
59
- </div>
60
- </div>
61
- );
62
- };
63
-
64
- export default ${pascalName};
65
- `;
66
- };
67
-
68
- export const buildVueComponent = (name, pascalName, options = {}) => {
69
- const atomsPackage = options.atomsPackage || null;
70
- const actionButton = atomsPackage
71
- ? ` <a-button
72
- :disabled="!canProceed"
73
- @click="handleAction"
74
- >
75
- {{ variant }}
76
- </a-button>`
77
- : ` <button
78
- type="button"
79
- class="${name}__action"
80
- :disabled="!canProceed"
81
- @click="handleAction"
82
- >
83
- {{ variant }}
84
- </button>`;
85
-
86
- return `<script setup lang="ts">
87
- import type { ${pascalName}Props, ${pascalName}Emits } from './types';
88
- import { use${pascalName}Controller } from './${name}.controller';
89
-
90
- const props = withDefaults(defineProps<${pascalName}Props>(), {
91
- variant: 'standard'
92
- });
93
-
94
- const emit = defineEmits<${pascalName}Emits>();
95
-
96
- const { state, canProceed, descriptor, handleAction } = use${pascalName}Controller({
97
- initialState: { status: 'idle' },
98
- onAction: () => emit('action', props.title)
99
- });
100
- </script>
101
-
102
- <template>
103
- <div class="${name}">
104
- <div class="${name}__header">
105
- <h3 class="${name}__title">{{ title }}</h3>
106
- <p v-if="subtitle" class="${name}__subtitle">{{ subtitle }}</p>
107
- <span :class="descriptor.className">{{ descriptor.text }}</span>
108
- </div>
109
- <div class="${name}__body">
110
- ${actionButton}
111
- </div>
112
- </div>
113
- </template>
114
-
115
- <style lang="scss" scoped>
116
- @use './_${name}.scss';
117
- </style>
118
- `;
119
- };
120
-
121
- export const buildSvelteComponent = (name, pascalName, options = {}) => {
122
- const atomsPackage = options.atomsPackage || null;
123
- const atomImport = atomsPackage ? `import { AtomButton } from '${atomsPackage}';\n` : '';
124
- const actionButton = atomsPackage
125
- ? ` <AtomButton
126
- disabled={!controller.canProceed}
127
- onclick={controller.handleAction}
128
- >
129
- {variant}
130
- </AtomButton>`
131
- : ` <button
132
- type="button"
133
- class="${name}__action"
134
- disabled={!controller.canProceed}
135
- onclick={controller.handleAction}
136
- >
137
- {variant}
138
- </button>`;
139
-
140
- return `<script lang="ts">
141
- import type { ${pascalName}Props } from './types';
142
- ${atomImport}import { create${pascalName}Controller } from './${name}.controller';
143
-
144
- const {
145
- title,
146
- subtitle = '',
147
- variant = 'standard',
148
- onAction
149
- }: ${pascalName}Props = $props();
150
-
151
- const controller = create${pascalName}Controller({
152
- initialState: { status: 'idle' },
153
- onAction
154
- });
155
- </script>
156
-
157
- <div class="${name}">
158
- <div class="${name}__header">
159
- <h3 class="${name}__title">{title}</h3>
160
- {#if subtitle}
161
- <p class="${name}__subtitle">{subtitle}</p>
162
- {/if}
163
- <span class={controller.descriptor.className}>{controller.descriptor.text}</span>
164
- </div>
165
- <div class="${name}__body">
166
- ${actionButton}
167
- </div>
168
- </div>
169
-
170
- <style lang="scss">
171
- @use './_${name}.scss';
172
- </style>
173
- `;
174
- };
175
-
176
- export const buildController = (name, pascalName) => `import { useState, useMemo } from 'react';
177
- import type { ${pascalName}State, ${pascalName}Descriptor } from './types';
178
-
179
- interface ControllerOptions {
180
- readonly initialState?: ${pascalName}State;
181
- readonly onAction?: () => void;
182
- }
183
-
184
- export const use${pascalName}Controller = (options: ControllerOptions = {}) => {
185
- const [state, setState] = useState<${pascalName}State>(
186
- options.initialState || { status: 'idle' }
187
- );
188
-
189
- const isIdle = state.status === 'idle';
190
- const isPending = state.status === 'loading';
191
- const canProceed = isIdle && !isPending;
192
-
193
- const descriptor: ${pascalName}Descriptor = useMemo(() => {
194
- if (state.status === 'loading') {
195
- return { text: 'Loading...', className: '${name}__badge ${name}__badge--pending' };
196
- }
197
- if (state.status === 'active') {
198
- return { text: 'Active', className: '${name}__badge ${name}__badge--active' };
199
- }
200
- return { text: 'Ready', className: '${name}__badge ${name}__badge--ready' };
201
- }, [state.status]);
202
-
203
- const handleAction = () => {
204
- if (!canProceed) return;
205
- setState({ status: 'active', activeId: 'item-1' });
206
- options.onAction?.();
207
- };
208
-
209
- return { state, canProceed, descriptor, handleAction };
210
- };
211
- `;
212
-
213
- export const buildPropsType = (name, pascalName) => `export interface ${pascalName}Props {
214
- readonly title: string;
215
- readonly subtitle?: string;
216
- readonly variant?: 'standard' | 'highlight';
217
- readonly onAction?: () => void;
218
- }
219
-
220
- export interface ${pascalName}Emits {
221
- (e: 'action', title: string): void;
222
- }
223
- `;
224
-
225
- export const buildStateType = (name, pascalName) => `export type ${pascalName}State =
226
- | { readonly status: 'idle' }
227
- | { readonly status: 'loading'; readonly progress: number }
228
- | { readonly status: 'active'; readonly activeId: string }
229
- | { readonly status: 'fault'; readonly faultMessage: string };
230
-
231
- export interface ${pascalName}Descriptor {
232
- readonly text: string;
233
- readonly className: string;
234
- }
235
- `;
236
-
237
- export const buildTypesIndex = (fileNames = ['props', 'state']) =>
238
- fileNames.map((f) => `export type * from './${f}.d.ts';`).join('\n') + '\n';
239
-
240
- export const buildTypes = (name, pascalName) => `${buildStateType(name, pascalName)}
241
- ${buildPropsType(name, pascalName)}`;
242
-
243
- export const buildComponentSpec = (name, pascalName, hasController = true) => {
244
- if (hasController) {
245
- return `import { describe, it } from 'node:test';
246
- import assert from 'node:assert/strict';
247
- import { use${pascalName}Controller } from './${name}.controller.ts';
248
-
249
- describe('${pascalName} Capsule Controller', () => {
250
- it('exports pure controller hook', () => {
251
- assert.equal(typeof use${pascalName}Controller, 'function');
252
- });
253
- });
254
- `;
255
- }
256
-
257
- return `import { describe, it } from 'node:test';
258
- import assert from 'node:assert/strict';
259
-
260
- describe('${pascalName} Atom Foundation', () => {
261
- it('defines foundational UI atom contract', () => {
262
- assert.ok(true);
263
- });
264
- });
265
- `;
266
- };
267
-
268
- export const buildScss = (name) => `.${name} {
269
- display: flex;
270
- flex-direction: column;
271
- padding: 16px;
272
- background: rgba(19, 30, 58, 0.7);
273
- backdrop-filter: blur(12px);
274
- border: 1px solid rgba(98, 201, 255, 0.15);
275
- border-radius: 8px;
276
-
277
- &__header {
278
- display: flex;
279
- justify-content: space-between;
280
- align-items: center;
281
- }
282
-
283
- &__title {
284
- margin: 0;
285
- font-size: 16px;
286
- color: #ffffff;
287
- }
288
-
289
- &__subtitle {
290
- margin: 4px 0 0;
291
- font-size: 12px;
292
- color: #94a3b8;
293
- }
294
-
295
- &__badge {
296
- font-size: 11px;
297
- padding: 2px 8px;
298
- border-radius: 4px;
299
- background: #0b1329;
300
-
301
- &--ready { color: #62c9ff; }
302
- &--active { color: #4ade80; }
303
- &--pending { color: #facc15; }
304
- }
305
-
306
- &__body {
307
- margin-top: 14px;
308
- display: flex;
309
- justify-content: flex-end;
310
- }
311
-
312
- &__action {
313
- padding: 6px 14px;
314
- border-radius: 4px;
315
- background: #1e293b;
316
- border: 1px solid #334155;
317
- color: #ffffff;
318
- cursor: pointer;
319
-
320
- &:hover:not(:disabled) {
321
- background: #334155;
322
- border-color: #62c9ff;
323
- }
324
-
325
- &:disabled {
326
- opacity: 0.5;
327
- cursor: not-allowed;
328
- }
329
- }
330
- }
331
- `;
332
-
333
- export const buildIndex = (name, pascalName, ext) => {
334
- const compExport = ext === 'vue' || ext === 'svelte'
335
- ? `export { default as ${pascalName} } from './${name}.${ext}';`
336
- : `export { ${pascalName} } from './${name}';`;
337
-
338
- return `${compExport}
339
- export { use${pascalName}Controller } from './${name}.controller';
340
- export type * from './types';
341
- `;
342
- };
343
-
344
- export const buildHook = (name, camelName, pascalName) => `import { useState, useCallback, useEffect } from 'react';
345
- import type { ${pascalName}HookOptions, ${pascalName}HookReturn } from './types';
346
-
347
- export const ${camelName} = (options: ${pascalName}HookOptions = {}): ${pascalName}HookReturn => {
348
- const [data, setData] = useState<string | null>(null);
349
- const [isLoading, setIsLoading] = useState<boolean>(false);
350
- const [error, setError] = useState<string | null>(null);
351
-
352
- const execute = useCallback(async () => {
353
- setIsLoading(true);
354
- setError(null);
355
- try {
356
- setData('ready');
357
- options.onSuccess?.();
358
- } catch (err) {
359
- const message = err instanceof Error ? err.message : String(err);
360
- setError(message);
361
- } finally {
362
- setIsLoading(false);
363
- }
364
- }, [options]);
365
-
366
- useEffect(() => {
367
- if (options.immediate) {
368
- execute();
369
- }
370
- }, [options.immediate, execute]);
371
-
372
- return { data, isLoading, error, execute };
373
- };
374
- `;
375
-
376
- export const buildHookOptionsType = (pascalName) => `export interface ${pascalName}HookOptions {
377
- readonly immediate?: boolean;
378
- readonly onSuccess?: () => void;
379
- }
380
- `;
381
-
382
- export const buildHookReturnType = (pascalName) => `export interface ${pascalName}HookReturn {
383
- readonly data: string | null;
384
- readonly isLoading: boolean;
385
- readonly error: string | null;
386
- readonly execute: () => Promise<void>;
387
- }
388
- `;
389
-
390
- export const buildHookIndex = (name, camelName) => `export { ${camelName} } from './${name}';
391
- export type * from './types';
392
- `;
393
-
394
- export const buildHookSpec = (name, camelName) => `import { describe, it } from 'node:test';
395
- import assert from 'node:assert/strict';
396
- import { ${camelName} } from './${name}.ts';
397
-
398
- describe('${camelName} Hook Composable', () => {
399
- it('exports pure hook function', () => {
400
- assert.equal(typeof ${camelName}, 'function');
401
- });
402
- });
403
- `;
404
-
405
- export const buildReactView = (name, pascalName) => `import React from 'react';
406
- import type { ${pascalName}ViewParams } from './types';
407
-
408
- export const ${pascalName}View: React.FC<${pascalName}ViewParams> = ({
409
- HeaderMolecule,
410
- MainOrganism,
411
- FooterMolecule
412
- }) => (
413
- <main className="${name}">
414
- {HeaderMolecule}
415
- {MainOrganism}
416
- {FooterMolecule}
417
- </main>
418
- );
419
-
420
- export default ${pascalName}View;
421
- `;
422
-
423
- export const buildVueView = (name, pascalName) => `<script setup lang="ts">
424
- import type { ${pascalName}ViewParams } from './types';
425
-
426
- defineProps<${pascalName}ViewParams>();
427
- </script>
428
-
429
- <template>
430
- <main class="${name}">
431
- <component :is="HeaderMolecule" />
432
- <component :is="MainOrganism" />
433
- <component :is="FooterMolecule" />
434
- </main>
435
- </template>
436
- `;
437
-
438
- export const buildSvelteView = (name, pascalName) => `<script lang="ts">
439
- import type { ${pascalName}ViewParams } from './types';
440
-
441
- const {
442
- HeaderMolecule,
443
- MainOrganism,
444
- FooterMolecule
445
- }: ${pascalName}ViewParams = $props();
446
- </script>
447
-
448
- <main class="${name}">
449
- {@render HeaderMolecule?.()}
450
- {@render MainOrganism?.()}
451
- {@render FooterMolecule?.()}
452
- </main>
453
- `;
454
-
455
- export const buildViewParamsType = (pascalName) => `export interface ${pascalName}ViewParams {
456
- readonly HeaderMolecule?: unknown;
457
- readonly MainOrganism?: unknown;
458
- readonly FooterMolecule?: unknown;
459
- }
460
- `;
461
-
462
- export const buildViewIndex = (name, pascalName, ext) => {
463
- const compExport = ext === 'vue' || ext === 'svelte'
464
- ? `export { default as ${pascalName}View } from './${name}.${ext}';`
465
- : `export { ${pascalName}View } from './${name}';`;
466
-
467
- return `${compExport}
468
- export type * from './types';
469
- `;
470
- };
471
-
472
- export const buildViewSpec = (name, pascalName) => `import { describe, it } from 'node:test';
473
- import assert from 'node:assert/strict';
474
-
475
- describe('${pascalName}View Table of Contents', () => {
476
- it('defines pure declarative blueprint layout', () => {
477
- assert.ok(true);
478
- });
479
- });
480
- `;
1
+ export { toPascalCase, toCamelCase } from './generator-templates/naming.js';
2
+ export { buildReactComponent } from './generator-templates/react.js';
3
+ export { buildVueComponent } from './generator-templates/vue.js';
4
+ export { buildSvelteComponent } from './generator-templates/svelte.js';
5
+ export { buildController } from './generator-templates/controller.js';
6
+ export { buildComponentSpec, buildIndex } from './generator-templates/specs.js';
7
+ export {
8
+ buildPropsType,
9
+ buildStateType,
10
+ buildTypesIndex,
11
+ buildTypes
12
+ } from './generator-templates/types.js';
13
+ export { buildScss } from './generator-templates/styles.js';
14
+ export {
15
+ buildHook,
16
+ buildHookOptionsType,
17
+ buildHookReturnType,
18
+ buildHookIndex,
19
+ buildHookSpec
20
+ } from './generator-templates/hooks.js';
21
+ export {
22
+ buildReactView,
23
+ buildVueView,
24
+ buildSvelteView,
25
+ buildViewParamsType,
26
+ buildViewIndex,
27
+ buildViewSpec
28
+ } from './generator-templates/views.js';