@nqlib/nqui 0.1.1 → 0.1.3

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.
@@ -0,0 +1,76 @@
1
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
2
+ import { join, resolve } from 'path';
3
+ import { getPackageRoot } from './getPackageRoot.js';
4
+ import { findMainCssFile } from './framework.js';
5
+ import { askQuestion } from './wizard.js';
6
+
7
+ /**
8
+ * Copy Next.js example files to user's project
9
+ */
10
+ export async function copyNextJsExamples(framework, { force }) {
11
+ if (framework !== 'nextjs') {
12
+ return;
13
+ }
14
+
15
+ const root = getPackageRoot();
16
+ const examplesDir = join(root, 'scripts', 'examples');
17
+ const cwd = process.cwd();
18
+
19
+ // Determine app directory (src/app or app)
20
+ const appDir = existsSync(join(cwd, 'src', 'app'))
21
+ ? join(cwd, 'src', 'app')
22
+ : join(cwd, 'app');
23
+
24
+ const examples = [
25
+ { src: 'nextjs-page.tsx', dest: join(appDir, 'page.tsx'), name: 'page.tsx' },
26
+ { src: 'nextjs-layout.tsx', dest: join(appDir, 'layout.tsx'), name: 'layout.tsx' },
27
+ ];
28
+
29
+ const copied = [];
30
+ const existing = [];
31
+
32
+ // Check which files exist
33
+ for (const { dest, name } of examples) {
34
+ if (existsSync(dest)) {
35
+ existing.push({ dest, name });
36
+ }
37
+ }
38
+
39
+ // Ask about overwriting if files exist and force is not set
40
+ let shouldOverwrite = force;
41
+ if (existing.length > 0 && !force) {
42
+ const fileList = existing.map(e => e.name).join(' and ');
43
+ const answer = await askQuestion(
44
+ `\n⚠️ ${fileList} already exist(s). Overwrite? (y/n): `
45
+ );
46
+ shouldOverwrite = answer === 'y';
47
+ }
48
+
49
+ for (const { src, dest, name } of examples) {
50
+ const srcPath = join(examplesDir, src);
51
+
52
+ if (!existsSync(srcPath)) {
53
+ console.warn(`⚠️ Example file not found: ${srcPath}`);
54
+ continue;
55
+ }
56
+
57
+ if (existsSync(dest) && !shouldOverwrite) {
58
+ console.log(`⏭️ Skipped: ${dest} (already exists)`);
59
+ continue;
60
+ }
61
+
62
+ const content = readFileSync(srcPath, 'utf8');
63
+ writeFileSync(dest, content, 'utf8');
64
+ copied.push(dest);
65
+ console.log(`✅ ${existsSync(dest) && shouldOverwrite ? 'Overwritten' : 'Created'}: ${dest}`);
66
+ }
67
+
68
+ if (copied.length > 0) {
69
+ console.log(`\n📝 Required dependencies for example files:`);
70
+ console.log(` npm install @nqlib/nqui tw-animate-css next-themes\n`);
71
+ console.log(` Make sure your globals.css includes the setup from nqui/nqui-setup.css\n`);
72
+ }
73
+
74
+ return copied;
75
+ }
76
+
@@ -0,0 +1,68 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { join } from 'path';
3
+
4
+ /**
5
+ * Detect the framework type of the current project
6
+ */
7
+ export function detectFramework() {
8
+ const cwd = process.cwd();
9
+
10
+ if (
11
+ existsSync(join(cwd, 'next.config.js')) ||
12
+ existsSync(join(cwd, 'next.config.ts')) ||
13
+ existsSync(join(cwd, 'app')) ||
14
+ existsSync(join(cwd, 'src', 'app'))
15
+ ) {
16
+ return 'nextjs';
17
+ }
18
+
19
+ if (
20
+ existsSync(join(cwd, 'vite.config.js')) ||
21
+ existsSync(join(cwd, 'vite.config.ts'))
22
+ ) {
23
+ return 'vite';
24
+ }
25
+
26
+ if (existsSync(join(cwd, 'remix.config.js'))) {
27
+ return 'remix';
28
+ }
29
+
30
+ if (existsSync(join(cwd, 'src', 'index.css'))) {
31
+ return 'create-react-app';
32
+ }
33
+
34
+ return 'generic';
35
+ }
36
+
37
+ /**
38
+ * Find the main CSS file for a framework
39
+ */
40
+ export function findMainCssFile(framework) {
41
+ const cwd = process.cwd();
42
+
43
+ switch (framework) {
44
+ case 'nextjs':
45
+ // Check src/app first, then app
46
+ if (existsSync(join(cwd, 'src', 'app', 'globals.css'))) {
47
+ return 'src/app/globals.css';
48
+ }
49
+ if (existsSync(join(cwd, 'app', 'globals.css'))) {
50
+ return 'app/globals.css';
51
+ }
52
+ return 'app/globals.css'; // default
53
+ case 'vite':
54
+ case 'create-react-app':
55
+ if (existsSync(join(cwd, 'src', 'index.css'))) {
56
+ return 'src/index.css';
57
+ }
58
+ return 'src/index.css'; // default
59
+ case 'remix':
60
+ if (existsSync(join(cwd, 'app', 'root.css'))) {
61
+ return 'app/root.css';
62
+ }
63
+ return 'app/root.css'; // default
64
+ default:
65
+ return 'index.css';
66
+ }
67
+ }
68
+
@@ -0,0 +1,26 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ /**
6
+ * Robust package root detection that works with npx
7
+ * Uses fileURLToPath for Windows compatibility
8
+ */
9
+ export function getPackageRoot() {
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ let dir = dirname(__filename);
12
+
13
+ while (dir !== '/' && dir !== '') {
14
+ const pkgPath = join(dir, 'package.json');
15
+ if (existsSync(pkgPath)) {
16
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
17
+ if (pkg.name === '@nqlib/nqui') return dir;
18
+ }
19
+ const parentDir = dirname(dir);
20
+ if (parentDir === dir) break; // Reached root
21
+ dir = parentDir;
22
+ }
23
+
24
+ throw new Error('Could not locate @nqlib/nqui package root');
25
+ }
26
+
@@ -0,0 +1,34 @@
1
+ import { readFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { getPackageRoot } from './getPackageRoot.js';
4
+
5
+ export function printHelp() {
6
+ const root = getPackageRoot();
7
+ const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
8
+
9
+ console.log(`
10
+ ${pkg.name} v${pkg.version}
11
+
12
+ Usage:
13
+ npx nqui init-css [output.css] [options]
14
+
15
+ Options:
16
+ --js Generate JS token file
17
+ --tokens-only Extract only CSS variables
18
+ --setup Generate nqui-setup.css helper
19
+ --local-copy Generate local CSS copy instead of importing from library
20
+ --wizard Interactive installer
21
+ --force Overwrite existing files
22
+ --dry-run Preview output only
23
+ --help, -h Show help
24
+ --version, -v Show version
25
+
26
+ Examples:
27
+ npx nqui init-css
28
+ npx nqui init-css nqui/index.css
29
+ npx nqui init-css --local-copy nqui/nqui.css
30
+ npx nqui init-css --tokens-only --js
31
+ npx nqui init-css --wizard
32
+ `);
33
+ }
34
+