@blu1606/create-walrus-app 0.1.4 → 2.0.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.
Files changed (129) hide show
  1. package/dist/generator/file-ops.d.ts +8 -0
  2. package/dist/generator/file-ops.js +20 -0
  3. package/dist/generator/index.js +37 -22
  4. package/dist/generator/layers.d.ts +15 -2
  5. package/dist/generator/layers.js +38 -47
  6. package/dist/generator/types.d.ts +9 -1
  7. package/dist/index.js +1 -2
  8. package/dist/post-install/git.d.ts +8 -0
  9. package/dist/post-install/git.js +2 -0
  10. package/dist/post-install/index.d.ts +0 -1
  11. package/dist/post-install/index.js +2 -15
  12. package/dist/post-install/messages.js +1 -1
  13. package/package.json +68 -68
  14. package/{templates/base → presets/react-mysten-gallery}/.env.example +31 -31
  15. package/presets/react-mysten-gallery/.gitkeep +4 -0
  16. package/{templates/gallery → presets/react-mysten-gallery}/README.md +25 -22
  17. package/presets/react-mysten-gallery/package.json +34 -0
  18. package/presets/react-mysten-gallery/src/App.tsx +23 -0
  19. package/presets/react-mysten-gallery/src/components/features/file-card.tsx +89 -0
  20. package/{templates/gallery/src/components/GalleryGrid.tsx → presets/react-mysten-gallery/src/components/features/gallery-grid.tsx} +5 -5
  21. package/presets/react-mysten-gallery/src/components/features/upload-modal.tsx +69 -0
  22. package/{templates/react/src/components/WalletConnect.tsx → presets/react-mysten-gallery/src/components/features/wallet-connect.tsx} +1 -1
  23. package/presets/react-mysten-gallery/src/components/layout/app-layout.tsx +21 -0
  24. package/{templates/react/src/hooks/useStorage.ts → presets/react-mysten-gallery/src/hooks/use-download.ts} +2 -18
  25. package/presets/react-mysten-gallery/src/hooks/use-upload.ts +49 -0
  26. package/{templates/react/src/hooks/useWallet.ts → presets/react-mysten-gallery/src/hooks/use-wallet.ts} +2 -7
  27. package/presets/react-mysten-gallery/src/index.css +384 -0
  28. package/presets/react-mysten-gallery/src/index.ts +17 -0
  29. package/presets/react-mysten-gallery/src/lib/walrus/adapter.ts +197 -0
  30. package/presets/react-mysten-gallery/src/lib/walrus/client.ts +87 -0
  31. package/presets/react-mysten-gallery/src/lib/walrus/index.ts +4 -0
  32. package/presets/react-mysten-gallery/src/lib/walrus/types.ts +101 -0
  33. package/{templates/react → presets/react-mysten-gallery}/src/main.tsx +0 -1
  34. package/{templates/react → presets/react-mysten-gallery}/src/providers/WalletProvider.tsx +16 -1
  35. package/{templates/base → presets/react-mysten-gallery}/src/utils/env.ts +41 -41
  36. package/{templates/gallery → presets/react-mysten-gallery}/src/utils/index-manager.ts +2 -2
  37. package/presets/react-mysten-gallery/src/utils/mime-type.ts +97 -0
  38. package/presets/react-mysten-gallery/src/utils/preview-generator.ts +134 -0
  39. package/{templates/react → presets/react-mysten-gallery}/tsconfig.json +20 -8
  40. package/presets/react-mysten-simple-upload/.env.example +31 -0
  41. package/presets/react-mysten-simple-upload/.gitkeep +4 -0
  42. package/presets/react-mysten-simple-upload/index.html +13 -0
  43. package/{templates/react → presets/react-mysten-simple-upload}/package.json +13 -11
  44. package/presets/react-mysten-simple-upload/src/App.tsx +27 -0
  45. package/presets/react-mysten-simple-upload/src/components/features/file-preview.tsx +73 -0
  46. package/{templates/simple-upload/src/components/UploadForm.tsx → presets/react-mysten-simple-upload/src/components/features/upload-form.tsx} +15 -5
  47. package/presets/react-mysten-simple-upload/src/components/features/wallet-connect.tsx +21 -0
  48. package/presets/react-mysten-simple-upload/src/components/layout/app-layout.tsx +21 -0
  49. package/presets/react-mysten-simple-upload/src/hooks/use-download.ts +24 -0
  50. package/presets/react-mysten-simple-upload/src/hooks/use-upload.ts +49 -0
  51. package/presets/react-mysten-simple-upload/src/hooks/use-wallet.ts +11 -0
  52. package/presets/react-mysten-simple-upload/src/index.css +252 -0
  53. package/presets/react-mysten-simple-upload/src/index.ts +16 -0
  54. package/presets/react-mysten-simple-upload/src/lib/walrus/adapter.ts +197 -0
  55. package/presets/react-mysten-simple-upload/src/lib/walrus/client.ts +87 -0
  56. package/presets/react-mysten-simple-upload/src/lib/walrus/index.ts +4 -0
  57. package/{templates/base/src/adapters/storage.ts → presets/react-mysten-simple-upload/src/lib/walrus/types.ts} +83 -58
  58. package/presets/react-mysten-simple-upload/src/main.tsx +16 -0
  59. package/presets/react-mysten-simple-upload/src/providers/QueryProvider.tsx +18 -0
  60. package/presets/react-mysten-simple-upload/src/providers/WalletProvider.tsx +52 -0
  61. package/presets/react-mysten-simple-upload/src/utils/env.ts +41 -0
  62. package/presets/react-mysten-simple-upload/src/utils/mime-type.ts +97 -0
  63. package/presets/react-mysten-simple-upload/tsconfig.json +39 -0
  64. package/presets/react-mysten-simple-upload/tsconfig.node.json +10 -0
  65. package/presets/react-mysten-simple-upload/vite.config.ts +19 -0
  66. package/dist/__tests__/helpers/adapter-compliance.d.ts +0 -2
  67. package/dist/__tests__/helpers/adapter-compliance.js +0 -47
  68. package/dist/__tests__/helpers/fixtures.d.ts +0 -21
  69. package/dist/__tests__/helpers/fixtures.js +0 -30
  70. package/dist/__tests__/helpers/fs-helpers.d.ts +0 -12
  71. package/dist/__tests__/helpers/fs-helpers.js +0 -35
  72. package/dist/__tests__/helpers/index.d.ts +0 -4
  73. package/dist/__tests__/helpers/index.js +0 -4
  74. package/dist/__tests__/helpers/test-hooks.d.ts +0 -3
  75. package/dist/__tests__/helpers/test-hooks.js +0 -18
  76. package/dist/context.test.d.ts +0 -1
  77. package/dist/context.test.js +0 -98
  78. package/dist/generator/index.test.d.ts +0 -1
  79. package/dist/generator/index.test.js +0 -143
  80. package/dist/generator/layers.test.d.ts +0 -1
  81. package/dist/generator/layers.test.js +0 -92
  82. package/dist/generator/merge.test.d.ts +0 -1
  83. package/dist/generator/merge.test.js +0 -79
  84. package/dist/generator/transform.test.d.ts +0 -1
  85. package/dist/generator/transform.test.js +0 -51
  86. package/dist/matrix.test.d.ts +0 -1
  87. package/dist/matrix.test.js +0 -70
  88. package/dist/types.test.d.ts +0 -1
  89. package/dist/types.test.js +0 -65
  90. package/dist/utils/detect-pm.test.d.ts +0 -1
  91. package/dist/utils/detect-pm.test.js +0 -52
  92. package/dist/validator.test.d.ts +0 -1
  93. package/dist/validator.test.js +0 -96
  94. package/templates/base/README.md +0 -54
  95. package/templates/base/package.json +0 -19
  96. package/templates/base/src/types/index.ts +0 -9
  97. package/templates/base/src/types/walrus.ts +0 -22
  98. package/templates/base/src/utils/format.ts +0 -29
  99. package/templates/base/tsconfig.json +0 -19
  100. package/templates/gallery/package.json +0 -6
  101. package/templates/gallery/src/App.tsx +0 -21
  102. package/templates/gallery/src/components/FileCard.tsx +0 -27
  103. package/templates/gallery/src/components/UploadModal.tsx +0 -45
  104. package/templates/gallery/src/styles.css +0 -58
  105. package/templates/gallery/src/types/gallery.ts +0 -13
  106. package/templates/react/.eslintrc.json +0 -26
  107. package/templates/react/README.md +0 -80
  108. package/templates/react/src/App.tsx +0 -14
  109. package/templates/react/src/components/Layout.tsx +0 -21
  110. package/templates/react/src/dapp-kit.css +0 -1
  111. package/templates/react/src/index.css +0 -50
  112. package/templates/react/src/index.ts +0 -10
  113. package/templates/sdk-mysten/README.md +0 -65
  114. package/templates/sdk-mysten/package.json +0 -14
  115. package/templates/sdk-mysten/src/adapter.ts +0 -80
  116. package/templates/sdk-mysten/src/client.ts +0 -45
  117. package/templates/sdk-mysten/src/config.ts +0 -33
  118. package/templates/sdk-mysten/src/index.ts +0 -11
  119. package/templates/sdk-mysten/src/types.ts +0 -19
  120. package/templates/sdk-mysten/test/adapter.test.ts +0 -20
  121. package/templates/simple-upload/package.json +0 -6
  122. package/templates/simple-upload/src/App.tsx +0 -27
  123. package/templates/simple-upload/src/components/FilePreview.tsx +0 -40
  124. package/templates/simple-upload/src/styles.css +0 -33
  125. /package/{templates/react → presets/react-mysten-gallery}/index.html +0 -0
  126. /package/{templates/react → presets/react-mysten-gallery}/src/providers/QueryProvider.tsx +0 -0
  127. /package/{templates/react → presets/react-mysten-gallery}/tsconfig.node.json +0 -0
  128. /package/{templates/react → presets/react-mysten-gallery}/vite.config.ts +0 -0
  129. /package/{templates/simple-upload → presets/react-mysten-simple-upload}/README.md +0 -0
@@ -0,0 +1,39 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": [
6
+ "ES2020",
7
+ "DOM",
8
+ "DOM.Iterable"
9
+ ],
10
+ "module": "ESNext",
11
+ "skipLibCheck": true,
12
+ "moduleResolution": "bundler",
13
+ "allowImportingTsExtensions": true,
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true,
17
+ "jsx": "react-jsx",
18
+ "types": [
19
+ "vite/client"
20
+ ],
21
+ "strict": true,
22
+ "noUnusedLocals": true,
23
+ "noUnusedParameters": true,
24
+ "noFallthroughCasesInSwitch": true,
25
+ "paths": {
26
+ "@/*": [
27
+ "./src/*"
28
+ ]
29
+ }
30
+ },
31
+ "include": [
32
+ "src"
33
+ ],
34
+ "references": [
35
+ {
36
+ "path": "./tsconfig.node.json"
37
+ }
38
+ ]
39
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "skipLibCheck": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true
8
+ },
9
+ "include": ["vite.config.ts"]
10
+ }
@@ -0,0 +1,19 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ server: {
7
+ port: 3000,
8
+ open: true,
9
+ },
10
+ build: {
11
+ target: 'esnext',
12
+ outDir: 'dist',
13
+ },
14
+ resolve: {
15
+ alias: {
16
+ '@': '/src',
17
+ },
18
+ },
19
+ });
@@ -1,2 +0,0 @@
1
- import type { StorageAdapter } from '../../../../base/src/adapters/storage.js';
2
- export declare function testStorageAdapterCompliance(adapterName: string, adapter: StorageAdapter): void;
@@ -1,47 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- export function testStorageAdapterCompliance(adapterName, adapter) {
3
- describe(`${adapterName} StorageAdapter Compliance`, () => {
4
- describe('Interface Implementation', () => {
5
- it('should implement upload method', () => {
6
- expect(adapter.upload).toBeDefined();
7
- expect(typeof adapter.upload).toBe('function');
8
- });
9
- it('should implement download method', () => {
10
- expect(adapter.download).toBeDefined();
11
- expect(typeof adapter.download).toBe('function');
12
- });
13
- it('should implement getMetadata method', () => {
14
- expect(adapter.getMetadata).toBeDefined();
15
- expect(typeof adapter.getMetadata).toBe('function');
16
- });
17
- it('should implement delete method', () => {
18
- expect(adapter.delete).toBeDefined();
19
- expect(typeof adapter.delete).toBe('function');
20
- });
21
- });
22
- describe('Type Signatures', () => {
23
- it('upload should accept File and UploadOptions', async () => {
24
- const mockFile = new File(['test'], 'test.txt', { type: 'text/plain' });
25
- const mockOptions = { epochs: 1 };
26
- await expect(async () => {
27
- await adapter.upload(mockFile, mockOptions);
28
- }).rejects.toThrow();
29
- });
30
- it('download should accept string blobId', async () => {
31
- await expect(async () => {
32
- await adapter.download('test-blob-id');
33
- }).rejects.toThrow();
34
- });
35
- it('getMetadata should accept string blobId', async () => {
36
- await expect(async () => {
37
- await adapter.getMetadata('test-blob-id');
38
- }).rejects.toThrow();
39
- });
40
- it('delete should accept string blobId', async () => {
41
- await expect(async () => {
42
- await adapter.delete('test-blob-id');
43
- }).rejects.toThrow();
44
- });
45
- });
46
- });
47
- }
@@ -1,21 +0,0 @@
1
- export declare const MOCK_PACKAGE_JSON: {
2
- name: string;
3
- version: string;
4
- type: string;
5
- scripts: {
6
- dev: string;
7
- build: string;
8
- };
9
- dependencies: {
10
- react: string;
11
- };
12
- };
13
- export declare const MOCK_TSCONFIG: {
14
- compilerOptions: {
15
- target: string;
16
- module: string;
17
- strict: boolean;
18
- };
19
- };
20
- export declare const MOCK_VITE_CONFIG = "import { defineConfig } from 'vite';\nimport react from '@vitejs/plugin-react';\n\nexport default defineConfig({\n plugins: [react()],\n});\n";
21
- export declare const MOCK_README = "# Test Project\n\nThis is a test project.\n";
@@ -1,30 +0,0 @@
1
- export const MOCK_PACKAGE_JSON = {
2
- name: 'test-app',
3
- version: '0.1.0',
4
- type: 'module',
5
- scripts: {
6
- dev: 'vite',
7
- build: 'tsc && vite build',
8
- },
9
- dependencies: {
10
- react: '^18.2.0',
11
- },
12
- };
13
- export const MOCK_TSCONFIG = {
14
- compilerOptions: {
15
- target: 'ES2020',
16
- module: 'ESNext',
17
- strict: true,
18
- },
19
- };
20
- export const MOCK_VITE_CONFIG = `import { defineConfig } from 'vite';
21
- import react from '@vitejs/plugin-react';
22
-
23
- export default defineConfig({
24
- plugins: [react()],
25
- });
26
- `;
27
- export const MOCK_README = `# Test Project
28
-
29
- This is a test project.
30
- `;
@@ -1,12 +0,0 @@
1
- export declare function createTempDir(prefix?: string): Promise<string>;
2
- export declare function cleanupTempDir(dir: string): Promise<void>;
3
- export declare function createTestFile(dir: string, filename: string, content: string): Promise<string>;
4
- export declare function readTestFile(filePath: string): Promise<string>;
5
- export declare function createMockContext(overrides?: {}): {
6
- projectName: string;
7
- sdk: string;
8
- framework: string;
9
- useCase: string;
10
- tailwind: boolean;
11
- analytics: boolean;
12
- };
@@ -1,35 +0,0 @@
1
- import fs from 'fs-extra';
2
- import path from 'node:path';
3
- import { fileURLToPath } from 'node:url';
4
- const __filename = fileURLToPath(import.meta.url);
5
- const __dirname = path.dirname(__filename);
6
- export async function createTempDir(prefix = 'test-') {
7
- const tempDir = path.join(__dirname, '../../../.tmp', `${prefix}${Date.now()}`);
8
- await fs.ensureDir(tempDir);
9
- return tempDir;
10
- }
11
- export async function cleanupTempDir(dir) {
12
- if (await fs.pathExists(dir)) {
13
- await fs.remove(dir);
14
- }
15
- }
16
- export async function createTestFile(dir, filename, content) {
17
- const filePath = path.join(dir, filename);
18
- await fs.ensureDir(path.dirname(filePath));
19
- await fs.writeFile(filePath, content, 'utf-8');
20
- return filePath;
21
- }
22
- export async function readTestFile(filePath) {
23
- return await fs.readFile(filePath, 'utf-8');
24
- }
25
- export function createMockContext(overrides = {}) {
26
- return {
27
- projectName: 'test-project',
28
- sdk: 'mysten',
29
- framework: 'react',
30
- useCase: 'simple-upload',
31
- tailwind: false,
32
- analytics: false,
33
- ...overrides,
34
- };
35
- }
@@ -1,4 +0,0 @@
1
- export { createTempDir, cleanupTempDir, createTestFile, readTestFile, createMockContext, } from './fs-helpers.js';
2
- export { useTempDirectory } from './test-hooks.js';
3
- export { MOCK_PACKAGE_JSON, MOCK_TSCONFIG, MOCK_VITE_CONFIG, MOCK_README, } from './fixtures.js';
4
- export { testStorageAdapterCompliance } from './adapter-compliance.js';
@@ -1,4 +0,0 @@
1
- export { createTempDir, cleanupTempDir, createTestFile, readTestFile, createMockContext, } from './fs-helpers.js';
2
- export { useTempDirectory } from './test-hooks.js';
3
- export { MOCK_PACKAGE_JSON, MOCK_TSCONFIG, MOCK_VITE_CONFIG, MOCK_README, } from './fixtures.js';
4
- export { testStorageAdapterCompliance } from './adapter-compliance.js';
@@ -1,3 +0,0 @@
1
- export declare function useTempDirectory(): {
2
- readonly dir: string;
3
- };
@@ -1,18 +0,0 @@
1
- import { afterEach, beforeEach } from 'vitest';
2
- import { createTempDir, cleanupTempDir } from './fs-helpers.js';
3
- export function useTempDirectory() {
4
- let tempDir;
5
- beforeEach(async () => {
6
- tempDir = await createTempDir();
7
- });
8
- afterEach(async () => {
9
- if (tempDir) {
10
- await cleanupTempDir(tempDir);
11
- }
12
- });
13
- return {
14
- get dir() {
15
- return tempDir;
16
- },
17
- };
18
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,98 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from 'vitest';
2
- import { buildContext } from './context.js';
3
- import * as detectPmModule from './utils/detect-pm.js';
4
- // Mock the detectPackageManager function
5
- vi.mock('./utils/detect-pm.js', () => ({
6
- detectPackageManager: vi.fn(() => 'pnpm'),
7
- }));
8
- describe('buildContext', () => {
9
- beforeEach(() => {
10
- vi.clearAllMocks();
11
- });
12
- it('should build context from args only', () => {
13
- const args = {
14
- projectName: 'test-app',
15
- sdk: 'mysten',
16
- framework: 'react',
17
- useCase: 'simple-upload',
18
- analytics: true,
19
- tailwind: false,
20
- };
21
- const context = buildContext(args, {});
22
- expect(context.projectName).toBe('test-app');
23
- expect(context.sdk).toBe('mysten');
24
- expect(context.framework).toBe('react');
25
- expect(context.useCase).toBe('simple-upload');
26
- expect(context.analytics).toBe(true);
27
- expect(context.tailwind).toBe(false);
28
- expect(context.packageManager).toBe('pnpm');
29
- expect(context.projectPath).toMatch(/test-app$/);
30
- });
31
- it('should build context from prompt results only', () => {
32
- const promptResults = {
33
- projectName: 'prompt-app',
34
- sdk: 'tusky',
35
- framework: 'vue',
36
- useCase: 'gallery',
37
- analytics: false,
38
- tailwind: true,
39
- };
40
- const context = buildContext({}, promptResults);
41
- expect(context.projectName).toBe('prompt-app');
42
- expect(context.sdk).toBe('tusky');
43
- expect(context.framework).toBe('vue');
44
- expect(context.useCase).toBe('gallery');
45
- expect(context.analytics).toBe(false);
46
- expect(context.tailwind).toBe(true);
47
- });
48
- it('should prioritize args over prompt results', () => {
49
- const args = {
50
- projectName: 'args-app',
51
- sdk: 'mysten',
52
- };
53
- const promptResults = {
54
- projectName: 'prompt-app',
55
- sdk: 'tusky',
56
- framework: 'react',
57
- useCase: 'simple-upload',
58
- analytics: true,
59
- tailwind: true,
60
- };
61
- const context = buildContext(args, promptResults);
62
- expect(context.projectName).toBe('args-app');
63
- expect(context.sdk).toBe('mysten');
64
- expect(context.framework).toBe('react');
65
- expect(context.useCase).toBe('simple-upload');
66
- });
67
- it('should convert analytics to boolean correctly', () => {
68
- const base = { sdk: 'mysten', framework: 'react', useCase: 'simple-upload' };
69
- expect(buildContext({ projectName: 'test', analytics: true, ...base }, {}).analytics).toBe(true);
70
- expect(buildContext({ projectName: 'test', analytics: false, ...base }, {}).analytics).toBe(false);
71
- expect(buildContext({ projectName: 'test', analytics: 1, ...base }, {}).analytics).toBe(true);
72
- expect(buildContext({ projectName: 'test', analytics: 0, ...base }, {}).analytics).toBe(false);
73
- expect(buildContext({ projectName: 'test', analytics: 'yes', ...base }, {}).analytics).toBe(true);
74
- expect(buildContext({ projectName: 'test', analytics: '', ...base }, {}).analytics).toBe(false);
75
- });
76
- it('should convert tailwind to boolean correctly', () => {
77
- const base = { sdk: 'mysten', framework: 'react', useCase: 'simple-upload' };
78
- expect(buildContext({ projectName: 'test', tailwind: true, ...base }, {}).tailwind).toBe(true);
79
- expect(buildContext({ projectName: 'test', tailwind: false, ...base }, {}).tailwind).toBe(false);
80
- expect(buildContext({ projectName: 'test', tailwind: 1, ...base }, {}).tailwind).toBe(true);
81
- expect(buildContext({ projectName: 'test', tailwind: 0, ...base }, {}).tailwind).toBe(false);
82
- });
83
- it('should call detectPackageManager', () => {
84
- buildContext({ projectName: 'test', sdk: 'mysten', framework: 'react', useCase: 'simple-upload' }, {});
85
- expect(detectPmModule.detectPackageManager).toHaveBeenCalled();
86
- });
87
- it('should generate absolute projectPath', () => {
88
- const context = buildContext({ projectName: 'test-app', sdk: 'mysten', framework: 'react', useCase: 'simple-upload' }, {});
89
- expect(context.projectPath).toContain('test-app');
90
- expect(context.projectPath.length).toBeGreaterThan('test-app'.length);
91
- });
92
- it('should handle partial args and prompts', () => {
93
- const context = buildContext({ projectName: 'partial' }, { sdk: 'hibernuts', framework: 'react', useCase: 'simple-upload' });
94
- expect(context.projectName).toBe('partial');
95
- expect(context.sdk).toBe('hibernuts');
96
- expect(context.framework).toBe('react');
97
- });
98
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,143 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { generateProject } from './index.js';
3
- import fs from 'fs-extra';
4
- import path from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
- describe('generateProject integration', () => {
9
- const testOutputDir = path.join(__dirname, '../../test-output');
10
- const templateDir = path.join(__dirname, '../../templates');
11
- beforeEach(async () => {
12
- // Clean up test output directory
13
- await fs.remove(testOutputDir);
14
- });
15
- afterEach(async () => {
16
- // Clean up after tests
17
- await fs.remove(testOutputDir);
18
- });
19
- it('should generate project with all layers', async () => {
20
- const context = {
21
- projectName: 'test-walrus-app',
22
- projectPath: path.join(testOutputDir, 'test-walrus-app'),
23
- sdk: 'mysten',
24
- framework: 'react',
25
- useCase: 'simple-upload',
26
- analytics: false,
27
- tailwind: false,
28
- packageManager: 'pnpm',
29
- };
30
- const result = await generateProject({
31
- context,
32
- templateDir,
33
- targetDir: context.projectPath,
34
- });
35
- expect(result.success).toBe(true);
36
- expect(result.filesCreated).toBeGreaterThan(0);
37
- // Verify directory was created
38
- const exists = await fs.pathExists(context.projectPath);
39
- expect(exists).toBe(true);
40
- // Verify package.json was merged
41
- const pkgJsonPath = path.join(context.projectPath, 'package.json');
42
- const pkgJsonExists = await fs.pathExists(pkgJsonPath);
43
- expect(pkgJsonExists).toBe(true);
44
- const pkgJson = await fs.readJson(pkgJsonPath);
45
- expect(pkgJson.name).toBe('test-walrus-app');
46
- expect(pkgJson.dependencies['@mysten/walrus']).toBeDefined();
47
- expect(pkgJson.dependencies['react']).toBeDefined();
48
- expect(pkgJson.scripts.dev).toBeDefined();
49
- expect(pkgJson.scripts.upload).toBeDefined();
50
- });
51
- it('should transform template variables', async () => {
52
- const context = {
53
- projectName: 'my-custom-app',
54
- projectPath: path.join(testOutputDir, 'my-custom-app'),
55
- sdk: 'mysten',
56
- framework: 'react',
57
- useCase: 'simple-upload',
58
- analytics: false,
59
- tailwind: false,
60
- packageManager: 'npm',
61
- };
62
- const result = await generateProject({
63
- context,
64
- templateDir,
65
- targetDir: context.projectPath,
66
- });
67
- expect(result.success).toBe(true);
68
- // Check README transformation
69
- const readmePath = path.join(context.projectPath, 'README.md');
70
- const readmeExists = await fs.pathExists(readmePath);
71
- expect(readmeExists).toBe(true);
72
- const readmeContent = await fs.readFile(readmePath, 'utf-8');
73
- expect(readmeContent).toContain('my-custom-app');
74
- expect(readmeContent).toContain('react');
75
- expect(readmeContent).not.toContain('{{projectName}}');
76
- expect(readmeContent).not.toContain('{{framework}}');
77
- });
78
- it('should fail for non-empty directory', async () => {
79
- const context = {
80
- projectName: 'test-app',
81
- projectPath: path.join(testOutputDir, 'non-empty'),
82
- sdk: 'mysten',
83
- framework: 'react',
84
- useCase: 'simple-upload',
85
- analytics: false,
86
- tailwind: false,
87
- packageManager: 'pnpm',
88
- };
89
- // Create non-empty directory
90
- await fs.ensureDir(context.projectPath);
91
- await fs.writeFile(path.join(context.projectPath, 'existing.txt'), 'content');
92
- const result = await generateProject({
93
- context,
94
- templateDir,
95
- targetDir: context.projectPath,
96
- });
97
- expect(result.success).toBe(false);
98
- expect(result.error).toBeDefined();
99
- expect(result.error?.message).toContain('not empty');
100
- });
101
- it('should rollback on error', async () => {
102
- const context = {
103
- projectName: 'test-app',
104
- projectPath: path.join(testOutputDir, 'rollback-test'),
105
- sdk: 'mysten',
106
- framework: 'react',
107
- useCase: 'simple-upload',
108
- analytics: false,
109
- tailwind: false,
110
- packageManager: 'pnpm',
111
- };
112
- // This will succeed because templates exist
113
- const result = await generateProject({
114
- context,
115
- templateDir,
116
- targetDir: context.projectPath,
117
- });
118
- // Just verify it works for now - rollback is tested via non-empty dir test
119
- expect(result.success).toBe(true);
120
- });
121
- it('should handle dry run mode', async () => {
122
- const context = {
123
- projectName: 'dry-run-test',
124
- projectPath: path.join(testOutputDir, 'dry-run'),
125
- sdk: 'mysten',
126
- framework: 'react',
127
- useCase: 'simple-upload',
128
- analytics: false,
129
- tailwind: false,
130
- packageManager: 'pnpm',
131
- };
132
- const result = await generateProject({
133
- context,
134
- templateDir,
135
- targetDir: context.projectPath,
136
- dryRun: true,
137
- });
138
- expect(result.success).toBe(true);
139
- // Verify no files were actually created
140
- const exists = await fs.pathExists(context.projectPath);
141
- expect(exists).toBe(false);
142
- });
143
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,92 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { resolveLayers } from './layers.js';
3
- import path from 'node:path';
4
- describe('resolveLayers', () => {
5
- it('should resolve base layers in correct priority order', () => {
6
- const context = {
7
- projectName: 'test-app',
8
- projectPath: '/path/to/test-app',
9
- sdk: 'mysten',
10
- framework: 'react',
11
- useCase: 'simple-upload',
12
- analytics: false,
13
- tailwind: false,
14
- packageManager: 'pnpm',
15
- };
16
- const layers = resolveLayers(context);
17
- expect(layers.length).toBe(4);
18
- expect(layers[0].name).toBe('base');
19
- expect(layers[0].priority).toBe(1);
20
- expect(layers[1].name).toBe('sdk-mysten');
21
- expect(layers[1].priority).toBe(2);
22
- expect(layers[2].name).toBe('react');
23
- expect(layers[2].priority).toBe(3);
24
- expect(layers[3].name).toBe('simple-upload');
25
- expect(layers[3].priority).toBe(4);
26
- });
27
- it('should include tailwind layer when enabled', () => {
28
- const context = {
29
- projectName: 'test-app',
30
- projectPath: '/path/to/test-app',
31
- sdk: 'mysten',
32
- framework: 'react',
33
- useCase: 'gallery',
34
- analytics: false,
35
- tailwind: true,
36
- packageManager: 'pnpm',
37
- };
38
- const layers = resolveLayers(context);
39
- expect(layers.length).toBe(5);
40
- expect(layers[4].name).toBe('tailwind');
41
- expect(layers[4].priority).toBe(5);
42
- });
43
- it('should include analytics layer when enabled', () => {
44
- const context = {
45
- projectName: 'test-app',
46
- projectPath: '/path/to/test-app',
47
- sdk: 'mysten',
48
- framework: 'vue',
49
- useCase: 'defi-nft',
50
- analytics: true,
51
- tailwind: false,
52
- packageManager: 'npm',
53
- };
54
- const layers = resolveLayers(context);
55
- expect(layers.length).toBe(5);
56
- expect(layers[4].name).toBe('analytics');
57
- expect(layers[4].priority).toBe(6);
58
- });
59
- it('should include both optional layers when enabled', () => {
60
- const context = {
61
- projectName: 'test-app',
62
- projectPath: '/path/to/test-app',
63
- sdk: 'mysten',
64
- framework: 'plain-ts',
65
- useCase: 'simple-upload',
66
- analytics: true,
67
- tailwind: true,
68
- packageManager: 'yarn',
69
- };
70
- const layers = resolveLayers(context);
71
- expect(layers.length).toBe(6);
72
- expect(layers[4].name).toBe('tailwind');
73
- expect(layers[5].name).toBe('analytics');
74
- });
75
- it('should use correct template paths', () => {
76
- const context = {
77
- projectName: 'test-app',
78
- projectPath: '/path/to/test-app',
79
- sdk: 'mysten',
80
- framework: 'react',
81
- useCase: 'simple-upload',
82
- analytics: false,
83
- tailwind: false,
84
- packageManager: 'pnpm',
85
- };
86
- const layers = resolveLayers(context);
87
- layers.forEach((layer) => {
88
- expect(layer.path).toContain('templates');
89
- expect(path.isAbsolute(layer.path)).toBe(true);
90
- });
91
- });
92
- });
@@ -1 +0,0 @@
1
- export {};