@tavus/cvi-ui 0.0.1-beta.1

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 (67) hide show
  1. package/.prettierrc.js +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +91 -0
  4. package/dev-components/components/cvi-provider/index.tsx +9 -0
  5. package/dev-components/hooks/README.md +499 -0
  6. package/dev-components/hooks/cvi-events-hooks.tsx +168 -0
  7. package/dev-components/hooks/use-cvi-call.tsx +24 -0
  8. package/dev-components/hooks/use-local-camera.tsx +20 -0
  9. package/dev-components/hooks/use-local-microphone.tsx +20 -0
  10. package/dev-components/hooks/use-local-screenshare.tsx +32 -0
  11. package/dev-components/hooks/use-remote-participant-ids.tsx +7 -0
  12. package/dev-components/hooks/use-replica-ids.tsx +9 -0
  13. package/dev-components/hooks/use-request-permissions.tsx +24 -0
  14. package/dev-components/hooks/use-start-haircheck.tsx +60 -0
  15. package/dist/index.js +237334 -0
  16. package/dist/types/cli/add.d.ts +20 -0
  17. package/dist/types/cli/info.d.ts +2 -0
  18. package/dist/types/cli/init.d.ts +23 -0
  19. package/dist/types/components/highlighter.d.ts +6 -0
  20. package/dist/types/components/logger.d.ts +8 -0
  21. package/dist/types/components/spinner.d.ts +4 -0
  22. package/dist/types/constants/components.d.ts +59 -0
  23. package/dist/types/constants/config.d.ts +5 -0
  24. package/dist/types/constants/errors.d.ts +5 -0
  25. package/dist/types/constants/frameworks.d.ts +39 -0
  26. package/dist/types/index.d.ts +1 -0
  27. package/dist/types/preflights/preflight-add.d.ts +15 -0
  28. package/dist/types/preflights/preflight-init.d.ts +9 -0
  29. package/dist/types/utils/add-components.d.ts +5 -0
  30. package/dist/types/utils/get-config.d.ts +51 -0
  31. package/dist/types/utils/get-package-info.d.ts +2 -0
  32. package/dist/types/utils/get-package-manager.d.ts +4 -0
  33. package/dist/types/utils/get-project-info.d.ts +10 -0
  34. package/dist/types/utils/handle-error.d.ts +1 -0
  35. package/dist/types/utils/resolve-components-tree.d.ts +4 -0
  36. package/dist/types/utils/resolve-import.d.ts +2 -0
  37. package/dist/types/utils/update-dependencies.d.ts +4 -0
  38. package/dist/types/utils/update-files.d.ts +14 -0
  39. package/dist/typescript-DhnEO4aV.js +12 -0
  40. package/dist/typescript-XxXP1Woc.js +14 -0
  41. package/eslint.config.js +12 -0
  42. package/package.json +67 -0
  43. package/prepare-scripts/convert-to-js.js +152 -0
  44. package/prepare-scripts/create-templates.js +265 -0
  45. package/rollup.config.js +28 -0
  46. package/src/cli/add.ts +124 -0
  47. package/src/cli/info.ts +21 -0
  48. package/src/cli/init.ts +131 -0
  49. package/src/components/highlighter.ts +8 -0
  50. package/src/components/logger.ts +22 -0
  51. package/src/components/spinner.ts +13 -0
  52. package/src/constants/config.ts +7 -0
  53. package/src/constants/errors.ts +5 -0
  54. package/src/constants/frameworks.ts +40 -0
  55. package/src/index.ts +26 -0
  56. package/src/preflights/preflight-add.ts +56 -0
  57. package/src/preflights/preflight-init.ts +77 -0
  58. package/src/utils/add-components.ts +52 -0
  59. package/src/utils/get-config.ts +60 -0
  60. package/src/utils/get-package-info.ts +14 -0
  61. package/src/utils/get-package-manager.ts +45 -0
  62. package/src/utils/get-project-info.ts +144 -0
  63. package/src/utils/handle-error.ts +34 -0
  64. package/src/utils/resolve-components-tree.ts +35 -0
  65. package/src/utils/update-dependencies.ts +37 -0
  66. package/src/utils/update-files.ts +212 -0
  67. package/tsconfig.json +23 -0
@@ -0,0 +1,212 @@
1
+ import { existsSync, promises as fs } from 'fs';
2
+ import path from 'path';
3
+ import { Config } from '@/src/utils/get-config';
4
+ import { getProjectInfo } from '@/src/utils/get-project-info';
5
+ import { highlighter } from '@/src/components/highlighter';
6
+ import { logger } from '@/src/components/logger';
7
+ import { spinner } from '@/src/components/spinner';
8
+ import prompts from 'prompts';
9
+ import * as templates from '../templates';
10
+ import { components as COMPONENTS } from '../templates/components';
11
+
12
+ type ComponentKey = keyof typeof templates.tsx;
13
+
14
+ export async function updateFiles(
15
+ files: string[],
16
+ config: Config,
17
+ options: {
18
+ overwrite?: boolean;
19
+ force?: boolean;
20
+ silent?: boolean;
21
+ rootSpinner?: ReturnType<typeof spinner>;
22
+ isRemote?: boolean;
23
+ }
24
+ ) {
25
+ if (!files?.length) {
26
+ return {
27
+ filesCreated: [],
28
+ filesUpdated: [],
29
+ filesSkipped: [],
30
+ };
31
+ }
32
+ options = {
33
+ overwrite: false,
34
+ force: false,
35
+ silent: false,
36
+ isRemote: false,
37
+ ...options,
38
+ };
39
+ const filesCreatedSpinner = spinner(`Updating files.`, {
40
+ silent: options.silent,
41
+ })?.start();
42
+
43
+ const [projectInfo] = await Promise.all([getProjectInfo(config.resolvedPaths.cwd)]);
44
+
45
+ // TODO: make this configurable
46
+ const componentsPath = projectInfo?.isSrcDir ? 'src/components/cvi' : 'app/components/cvi';
47
+
48
+ const filesCreated = [];
49
+ const filesUpdated = [];
50
+ const filesSkipped = [];
51
+
52
+ for (const filename of files) {
53
+ const componentBasePath = COMPONENTS.find((component) => component.name === filename)?.path;
54
+ if (!componentBasePath) {
55
+ logger.warn(`Component ${filename} not found`);
56
+ continue;
57
+ }
58
+
59
+ let targetPath: string;
60
+ let targetDir: string;
61
+
62
+ // Handle different component types based on path structure
63
+ if (componentBasePath.startsWith('components/')) {
64
+ // For components: create folder with filename and index file inside
65
+ targetDir = path.join(config.resolvedPaths.cwd, componentsPath, componentBasePath);
66
+ targetPath = path.join(targetDir, `index.${config.tsx ? 'tsx' : 'jsx'}`);
67
+ } else if (componentBasePath.startsWith('hooks/')) {
68
+ // For hooks: create direct filename.tsx file
69
+ targetDir = path.join(config.resolvedPaths.cwd, componentsPath, 'hooks');
70
+ targetPath = path.join(targetDir, `${filename}.${config.tsx ? 'tsx' : 'jsx'}`);
71
+ } else {
72
+ // Fallback to original logic for other cases
73
+ targetPath = path.join(
74
+ config.resolvedPaths.cwd,
75
+ componentsPath,
76
+ componentBasePath,
77
+ `${filename}.${config.tsx ? 'tsx' : 'jsx'}`
78
+ );
79
+ targetDir = path.dirname(targetPath);
80
+ }
81
+
82
+ const existingTarget = existsSync(targetPath);
83
+
84
+ if (existingTarget && !options.overwrite) {
85
+ filesCreatedSpinner.stop();
86
+ if (options.rootSpinner) {
87
+ options.rootSpinner.stop();
88
+ }
89
+ const { overwrite } = await prompts({
90
+ type: 'confirm',
91
+ name: 'overwrite',
92
+ message: `The file ${highlighter.info(
93
+ filename
94
+ )} already exists. Would you like to overwrite?`,
95
+ initial: false,
96
+ });
97
+
98
+ if (!overwrite) {
99
+ filesSkipped.push(path.relative(config.resolvedPaths.cwd, targetPath));
100
+ if (options.rootSpinner) {
101
+ options.rootSpinner.start();
102
+ }
103
+ continue;
104
+ }
105
+ filesCreatedSpinner?.start();
106
+ if (options.rootSpinner) {
107
+ options.rootSpinner.start();
108
+ }
109
+ }
110
+
111
+ // Create the target directory if it doesn't exist
112
+ if (!existsSync(targetDir)) {
113
+ await fs.mkdir(targetDir, { recursive: true });
114
+ }
115
+ const template: {
116
+ type: string;
117
+ content: string;
118
+ styles?: string;
119
+ dependencies?: string[];
120
+ componentsDependencies?: string[];
121
+ } = templates[config.tsx ? 'tsx' : 'jsx'][filename as ComponentKey];
122
+ // Write the content from templates
123
+ if (template) {
124
+ let content = template.content;
125
+
126
+ // Add 'use client' directive for Next.js frameworks
127
+ if (
128
+ projectInfo?.framework?.name === 'next-app' ||
129
+ projectInfo?.framework?.name === 'next-pages'
130
+ ) {
131
+ content = `'use client';\n\n${content}`;
132
+ }
133
+
134
+ await fs.writeFile(targetPath, content);
135
+ if (template.styles && template.styles.length > 0) {
136
+ // For components, create CSS file in the same directory as the index file
137
+ const cssPath = path.join(targetDir, `${filename}.module.css`);
138
+ await fs.writeFile(cssPath, template.styles);
139
+ }
140
+ } else {
141
+ // For other components, we'll need to handle them differently
142
+ // This part needs to be implemented based on how other components are structured
143
+ logger.warn(`Component ${filename} is not yet implemented`);
144
+ continue;
145
+ }
146
+
147
+ if (existingTarget) {
148
+ filesUpdated.push(path.relative(config.resolvedPaths.cwd, targetPath));
149
+ } else {
150
+ filesCreated.push(path.relative(config.resolvedPaths.cwd, targetPath));
151
+ }
152
+ }
153
+
154
+ const hasUpdatedFiles = filesCreated.length || filesUpdated.length;
155
+ if (!hasUpdatedFiles && !filesSkipped.length) {
156
+ filesCreatedSpinner?.info('No files updated.');
157
+ }
158
+
159
+ if (filesCreated.length) {
160
+ filesCreatedSpinner?.succeed(
161
+ `Created ${filesCreated.length} ${filesCreated.length === 1 ? 'file' : 'files'}:`
162
+ );
163
+ if (!options.silent) {
164
+ for (const file of filesCreated) {
165
+ logger.log(` - ${file}`);
166
+ }
167
+ }
168
+ } else {
169
+ filesCreatedSpinner?.stop();
170
+ }
171
+
172
+ if (filesUpdated.length) {
173
+ spinner(`Updated ${filesUpdated.length} ${filesUpdated.length === 1 ? 'file' : 'files'}:`, {
174
+ silent: options.silent,
175
+ })?.info();
176
+ if (!options.silent) {
177
+ for (const file of filesUpdated) {
178
+ logger.log(` - ${file}`);
179
+ }
180
+ }
181
+ }
182
+
183
+ if (filesSkipped.length) {
184
+ spinner(
185
+ `Skipped ${filesSkipped.length} ${
186
+ filesSkipped.length === 1 ? 'file' : 'files'
187
+ }: (files might be identical, use --overwrite to overwrite)`,
188
+ {
189
+ silent: options.silent,
190
+ }
191
+ )?.info();
192
+ if (!options.silent) {
193
+ for (const file of filesSkipped) {
194
+ logger.log(` - ${file}`);
195
+ }
196
+ }
197
+ }
198
+
199
+ if (!options.silent) {
200
+ logger.break();
201
+ }
202
+
203
+ return {
204
+ filesCreated,
205
+ filesUpdated,
206
+ filesSkipped,
207
+ };
208
+ }
209
+
210
+ export async function getNormalizedFileContent(content: string) {
211
+ return content.replace(/\r\n/g, '\n').trim();
212
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "moduleResolution": "node",
6
+ "lib": ["ES2020"],
7
+ "declaration": true,
8
+ "declarationDir": "./dist/types",
9
+ "outDir": "./dist",
10
+ "rootDir": "./src",
11
+ "strict": true,
12
+ "esModuleInterop": true,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "resolveJsonModule": true,
16
+ "baseUrl": ".",
17
+ "paths": {
18
+ "@/*": ["./*"]
19
+ }
20
+ },
21
+ "include": ["src/**/*"],
22
+ "exclude": ["node_modules", "dist", "test", "src/templates"]
23
+ }