cognite-create 0.1.5 → 0.1.7
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/bin/index.js +142 -22
- package/package.json +1 -1
- package/templates/.cursor/rules/general.mdc +1 -1
package/bin/index.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
3
4
|
const { spawn } = require('node:child_process');
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
4
6
|
const fs = require('node:fs/promises');
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
5
8
|
const path = require('node:path');
|
|
6
9
|
|
|
10
|
+
const TW_ANIMATE_PACKAGE = 'tw-animate-css';
|
|
11
|
+
const TW_ANIMATE_VERSION = '^1.3.8';
|
|
12
|
+
|
|
7
13
|
async function main() {
|
|
8
14
|
const args = process.argv.slice(2);
|
|
9
15
|
|
|
@@ -54,18 +60,23 @@ async function addCogniteTemplates(projectDir) {
|
|
|
54
60
|
throw error;
|
|
55
61
|
}
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
await ensureTwAnimateCssInstalled(targetRoot);
|
|
64
|
+
|
|
65
|
+
const srcDirectory = path.join(targetRoot, 'src');
|
|
58
66
|
const templateFiles = await collectTemplateFiles(templateRoot);
|
|
59
67
|
|
|
68
|
+
await fs.mkdir(srcDirectory, { recursive: true });
|
|
69
|
+
|
|
60
70
|
for (const relativePath of templateFiles) {
|
|
61
71
|
const normalizedPath = normalizeRelativePath(relativePath);
|
|
62
72
|
const source = path.join(templateRoot, relativePath);
|
|
63
73
|
|
|
64
74
|
const pathSegments = normalizedPath.split('/');
|
|
65
75
|
|
|
66
|
-
if (pathSegments[0] === 'app') {
|
|
67
|
-
const target = path.join(
|
|
68
|
-
const isGlobalsCss =
|
|
76
|
+
if (pathSegments[0] === 'app' || pathSegments[0] === 'lib') {
|
|
77
|
+
const target = path.join(srcDirectory, ...pathSegments);
|
|
78
|
+
const isGlobalsCss =
|
|
79
|
+
pathSegments[0] === 'app' && pathSegments.length === 2 && pathSegments[1] === 'globals.css';
|
|
69
80
|
|
|
70
81
|
if (isGlobalsCss) {
|
|
71
82
|
await copyFileWithOverwrite(source, target);
|
|
@@ -105,19 +116,6 @@ async function copyFileWithOverwrite(source, target) {
|
|
|
105
116
|
console.log(`Replaced ${path.relative(process.cwd(), target)}`);
|
|
106
117
|
}
|
|
107
118
|
|
|
108
|
-
async function fileExists(filePath) {
|
|
109
|
-
try {
|
|
110
|
-
await fs.access(filePath);
|
|
111
|
-
return true;
|
|
112
|
-
} catch (error) {
|
|
113
|
-
if (error.code === 'ENOENT') {
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
throw error;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
119
|
async function collectTemplateFiles(rootDir) {
|
|
122
120
|
const files = [];
|
|
123
121
|
|
|
@@ -147,14 +145,136 @@ function normalizeRelativePath(relativePath) {
|
|
|
147
145
|
return relativePath.split(path.sep).join('/');
|
|
148
146
|
}
|
|
149
147
|
|
|
150
|
-
async function
|
|
151
|
-
const
|
|
148
|
+
async function ensureTwAnimateCssInstalled(targetRoot) {
|
|
149
|
+
const packageJsonPath = path.join(targetRoot, 'package.json');
|
|
150
|
+
let packageJson;
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, 'utf8');
|
|
154
|
+
packageJson = JSON.parse(packageJsonContent);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.warn(
|
|
157
|
+
`\nUnable to read or parse ${path.relative(process.cwd(), packageJsonPath)}. ` +
|
|
158
|
+
`Install ${TW_ANIMATE_PACKAGE}@${TW_ANIMATE_VERSION} manually.`
|
|
159
|
+
);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const hasDependency = Boolean(
|
|
164
|
+
(packageJson.dependencies && packageJson.dependencies[TW_ANIMATE_PACKAGE]) ||
|
|
165
|
+
(packageJson.devDependencies && packageJson.devDependencies[TW_ANIMATE_PACKAGE])
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
if (hasDependency) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const packageManager = await detectPackageManager(packageJson, targetRoot);
|
|
173
|
+
|
|
174
|
+
if (!packageManager) {
|
|
175
|
+
console.warn(
|
|
176
|
+
`\nCould not determine package manager for ${path.relative(process.cwd(), targetRoot)}. ` +
|
|
177
|
+
`Install ${TW_ANIMATE_PACKAGE}@${TW_ANIMATE_VERSION} manually.`
|
|
178
|
+
);
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
console.log(
|
|
183
|
+
`\nInstalling ${TW_ANIMATE_PACKAGE}@${TW_ANIMATE_VERSION} using ${packageManager}...`
|
|
184
|
+
);
|
|
185
|
+
await installDependency(packageManager, targetRoot, `${TW_ANIMATE_PACKAGE}@${TW_ANIMATE_VERSION}`);
|
|
186
|
+
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async function detectPackageManager(packageJson, targetRoot) {
|
|
191
|
+
if (packageJson.packageManager && typeof packageJson.packageManager === 'string') {
|
|
192
|
+
const [name] = packageJson.packageManager.split('@');
|
|
193
|
+
|
|
194
|
+
if (name) {
|
|
195
|
+
return name;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const candidates = [
|
|
200
|
+
{ name: 'pnpm', lockFile: 'pnpm-lock.yaml' },
|
|
201
|
+
{ name: 'yarn', lockFile: 'yarn.lock' },
|
|
202
|
+
{ name: 'bun', lockFile: 'bun.lockb' },
|
|
203
|
+
{ name: 'npm', lockFile: 'package-lock.json' },
|
|
204
|
+
];
|
|
205
|
+
|
|
206
|
+
for (const candidate of candidates) {
|
|
207
|
+
const lockFilePath = path.join(targetRoot, candidate.lockFile);
|
|
208
|
+
|
|
209
|
+
if (await pathExists(lockFilePath)) {
|
|
210
|
+
return candidate.name;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function installDependency(packageManager, cwd, dependencySpec) {
|
|
218
|
+
const { command, args } = getInstallCommand(packageManager, dependencySpec);
|
|
152
219
|
|
|
153
|
-
if (
|
|
154
|
-
|
|
220
|
+
if (!command) {
|
|
221
|
+
throw new Error(`Unsupported package manager: ${packageManager}`);
|
|
155
222
|
}
|
|
156
223
|
|
|
157
|
-
return
|
|
224
|
+
return new Promise((resolve, reject) => {
|
|
225
|
+
const child = spawn(command, args, { stdio: 'inherit', cwd });
|
|
226
|
+
|
|
227
|
+
child.on('error', reject);
|
|
228
|
+
child.on('close', (code) => {
|
|
229
|
+
if (code !== 0) {
|
|
230
|
+
const error = new Error(
|
|
231
|
+
`${packageManager} exited with code ${code} while installing ${dependencySpec}`
|
|
232
|
+
);
|
|
233
|
+
error.exitCode = code;
|
|
234
|
+
return reject(error);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
resolve();
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function getInstallCommand(packageManager, dependencySpec) {
|
|
243
|
+
const normalized = normalizeCommand(packageManager);
|
|
244
|
+
|
|
245
|
+
switch (packageManager) {
|
|
246
|
+
case 'npm':
|
|
247
|
+
return { command: normalized, args: ['install', dependencySpec] };
|
|
248
|
+
case 'pnpm':
|
|
249
|
+
return { command: normalized, args: ['add', dependencySpec] };
|
|
250
|
+
case 'yarn':
|
|
251
|
+
return { command: normalized, args: ['add', dependencySpec] };
|
|
252
|
+
case 'bun':
|
|
253
|
+
return { command: normalized, args: ['add', dependencySpec] };
|
|
254
|
+
default:
|
|
255
|
+
return { command: null, args: [] };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function normalizeCommand(command) {
|
|
260
|
+
if (process.platform === 'win32' && command !== 'bun') {
|
|
261
|
+
return `${command}.cmd`;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return command;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async function pathExists(filePath) {
|
|
268
|
+
try {
|
|
269
|
+
await fs.access(filePath);
|
|
270
|
+
return true;
|
|
271
|
+
} catch (error) {
|
|
272
|
+
if (error && error.code === 'ENOENT') {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
throw error;
|
|
277
|
+
}
|
|
158
278
|
}
|
|
159
279
|
|
|
160
280
|
main().catch((error) => {
|
package/package.json
CHANGED
|
@@ -4,4 +4,4 @@ globs:
|
|
|
4
4
|
alwaysApply: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Use the ShadCN MCP server to check the Cognite registry for components you could use before making your own. If there are Cognite components available for what you are trying to do you must always use them over alternatives. We want to make sure our app aligns with the Cognite design system.
|