@mastorscdn/core 1.0.0 → 1.0.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.
- package/README.md +1 -1
- package/importer.js +81 -0
- package/index.d.ts +29 -0
- package/index.js +39 -0
- package/package.json +34 -21
- package/scripts/postinstall.js +325 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Enterprise-grade SCSS foundational architecture for the Mastors CDN ecosystem.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@mastorscdn/core)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](https://sass-lang.com)
|
|
8
8
|
|
package/importer.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// @mastorscdn/core | importer.js
|
|
3
|
+
// Custom Sass FileImporter — resolves `@mastorscdn/core` imports to the
|
|
4
|
+
// correct SCSS path without requiring --load-path in every sass command.
|
|
5
|
+
//
|
|
6
|
+
// Usage in Node.js sass API:
|
|
7
|
+
// const sass = require('sass');
|
|
8
|
+
// const { importer } = require('@mastorscdn/core/importer');
|
|
9
|
+
//
|
|
10
|
+
// sass.compile('src/main.scss', { importers: [importer] });
|
|
11
|
+
//
|
|
12
|
+
// (Bundlers like Vite/Next/Nuxt use loadPaths config instead — no importer needed.)
|
|
13
|
+
// =============================================================================
|
|
14
|
+
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const fs = require('fs');
|
|
19
|
+
const url = require('url');
|
|
20
|
+
|
|
21
|
+
// Absolute path to this package's scss/ folder
|
|
22
|
+
const SCSS_ROOT = path.resolve(__dirname, 'scss');
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Dart Sass FileImporter that resolves `@mastorscdn/core` and
|
|
26
|
+
* `@mastorscdn/core/<sub-path>` to real .scss files on disk.
|
|
27
|
+
*/
|
|
28
|
+
const importer = {
|
|
29
|
+
/**
|
|
30
|
+
* @param {string} importUrl - The string after @use / @import
|
|
31
|
+
* @returns {{ url: URL } | null}
|
|
32
|
+
*/
|
|
33
|
+
findFileUrl(importUrl) {
|
|
34
|
+
if (!importUrl.startsWith('@mastorscdn/core')) return null;
|
|
35
|
+
|
|
36
|
+
// Strip package name prefix, keep optional sub-path
|
|
37
|
+
const sub = importUrl.replace(/^@mastorscdn\/core\/?/, '');
|
|
38
|
+
|
|
39
|
+
const target = sub
|
|
40
|
+
? path.join(SCSS_ROOT, sub)
|
|
41
|
+
: path.join(SCSS_ROOT, '_index.scss');
|
|
42
|
+
|
|
43
|
+
// Resolution order (mirrors Sass partial resolution)
|
|
44
|
+
const candidates = sub
|
|
45
|
+
? [
|
|
46
|
+
target + '.scss',
|
|
47
|
+
path.join(path.dirname(target), '_' + path.basename(target) + '.scss'),
|
|
48
|
+
path.join(target, '_index.scss'),
|
|
49
|
+
target,
|
|
50
|
+
]
|
|
51
|
+
: [target];
|
|
52
|
+
|
|
53
|
+
for (const candidate of candidates) {
|
|
54
|
+
if (fs.existsSync(candidate)) {
|
|
55
|
+
return { url: url.pathToFileURL(candidate) };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return null; // fall through to Sass default resolution
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Returns the node_modules directory that contains @mastorscdn/core.
|
|
65
|
+
* Pass this as a loadPaths entry in your bundler.
|
|
66
|
+
*/
|
|
67
|
+
function getNodeModulesPath() {
|
|
68
|
+
// __dirname is .../node_modules/@mastorscdn/core
|
|
69
|
+
// So node_modules is two levels up
|
|
70
|
+
return path.resolve(__dirname, '..', '..');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Returns the package root (parent of scss/).
|
|
75
|
+
* Use as --load-path value when running sass CLI.
|
|
76
|
+
*/
|
|
77
|
+
function getLoadPath() {
|
|
78
|
+
return __dirname;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = { importer, getLoadPath, getNodeModulesPath };
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// @mastorscdn/core | index.d.ts
|
|
3
|
+
// TypeScript type declarations
|
|
4
|
+
// =============================================================================
|
|
5
|
+
|
|
6
|
+
import type { FileImporter } from 'sass';
|
|
7
|
+
|
|
8
|
+
/** Sass FileImporter — pass to sass.compile({ importers: [importer] }) */
|
|
9
|
+
export declare const importer: FileImporter<'sync'>;
|
|
10
|
+
|
|
11
|
+
/** Returns the package root path (use as --load-path) */
|
|
12
|
+
export declare function getLoadPath(): string;
|
|
13
|
+
|
|
14
|
+
/** Returns the node_modules directory containing this package */
|
|
15
|
+
export declare function getNodeModulesPath(): string;
|
|
16
|
+
|
|
17
|
+
/** Ready-to-use array for Vite / Next.js sassOptions.loadPaths */
|
|
18
|
+
export declare const sassLoadPaths: string[];
|
|
19
|
+
|
|
20
|
+
/** Absolute path to scss/_index.scss (SCSS @use API entry) */
|
|
21
|
+
export declare const scssEntry: string;
|
|
22
|
+
|
|
23
|
+
/** Absolute path to scss/mastors-core.scss (CSS compile entry) */
|
|
24
|
+
export declare const scssCompileEntry: string;
|
|
25
|
+
|
|
26
|
+
/** Shape of mc.config.js */
|
|
27
|
+
export interface McConfig {
|
|
28
|
+
loadPaths?: string[];
|
|
29
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// @mastorscdn/core | index.js
|
|
3
|
+
// JavaScript entry point — exposes helpers for tooling integrations.
|
|
4
|
+
//
|
|
5
|
+
// What this gives you:
|
|
6
|
+
// const mc = require('@mastorscdn/core');
|
|
7
|
+
// mc.sassLoadPaths → pass to Vite / Next sassOptions.loadPaths
|
|
8
|
+
// mc.importer → pass to sass.compile({ importers: [mc.importer] })
|
|
9
|
+
// mc.scssEntry → absolute path to scss/_index.scss
|
|
10
|
+
// =============================================================================
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { importer, getLoadPath, getNodeModulesPath } = require('./importer');
|
|
16
|
+
|
|
17
|
+
const PKG_ROOT = path.resolve(__dirname);
|
|
18
|
+
const SCSS_ENTRY = path.join(PKG_ROOT, 'scss', '_index.scss');
|
|
19
|
+
const SCSS_COMPILE = path.join(PKG_ROOT, 'scss', 'mastors-core.scss');
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
/** Sass FileImporter for programmatic sass.compile() */
|
|
23
|
+
importer,
|
|
24
|
+
|
|
25
|
+
/** Absolute path to this package's root (for --load-path) */
|
|
26
|
+
getLoadPath,
|
|
27
|
+
|
|
28
|
+
/** Absolute path to node_modules containing this package */
|
|
29
|
+
getNodeModulesPath,
|
|
30
|
+
|
|
31
|
+
/** Ready-to-use array for Vite / Next.js sassOptions.loadPaths */
|
|
32
|
+
get sassLoadPaths() { return [getNodeModulesPath()]; },
|
|
33
|
+
|
|
34
|
+
/** scss/_index.scss — use for @use API (no CSS output) */
|
|
35
|
+
scssEntry: SCSS_ENTRY,
|
|
36
|
+
|
|
37
|
+
/** scss/mastors-core.scss — compile this for the full CSS bundle */
|
|
38
|
+
scssCompileEntry: SCSS_COMPILE,
|
|
39
|
+
};
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastorscdn/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Mastors-Core — foundational SCSS architecture for the Mastors CDN ecosystem",
|
|
5
|
-
"main":
|
|
6
|
-
"
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"sass": "scss/_index.scss",
|
|
7
8
|
"style": "dist/mastors-core.css",
|
|
8
9
|
"keywords": [
|
|
9
10
|
"scss",
|
|
@@ -36,34 +37,46 @@
|
|
|
36
37
|
"license": "MIT",
|
|
37
38
|
"exports": {
|
|
38
39
|
".": {
|
|
39
|
-
"sass":
|
|
40
|
-
"
|
|
40
|
+
"sass": "./scss/_index.scss",
|
|
41
|
+
"scss": "./scss/_index.scss",
|
|
42
|
+
"style": "./dist/mastors-core.css",
|
|
43
|
+
"require": "./index.js",
|
|
44
|
+
"import": "./index.js",
|
|
45
|
+
"default": "./dist/mastors-core.css"
|
|
41
46
|
},
|
|
42
|
-
"./
|
|
47
|
+
"./importer": "./importer.js",
|
|
48
|
+
"./scss": "./scss/_index.scss",
|
|
49
|
+
"./scss/*": "./scss/*",
|
|
50
|
+
"./dist/mastors-core.css": "./dist/mastors-core.css",
|
|
43
51
|
"./dist/mastors-core.min.css": "./dist/mastors-core.min.css"
|
|
44
52
|
},
|
|
45
53
|
"files": [
|
|
46
54
|
"dist/",
|
|
47
55
|
"scss/",
|
|
56
|
+
"scripts/",
|
|
57
|
+
"index.js",
|
|
58
|
+
"index.d.ts",
|
|
59
|
+
"importer.js",
|
|
48
60
|
"README.md",
|
|
49
61
|
"LICENSE"
|
|
50
62
|
],
|
|
51
63
|
"scripts": {
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"sass:
|
|
56
|
-
"sass:
|
|
57
|
-
"sass:
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
64
|
+
"postinstall": "node scripts/postinstall.js",
|
|
65
|
+
"build": "vite build",
|
|
66
|
+
"dev": "vite",
|
|
67
|
+
"sass:build": "sass scss/mastors-core.scss dist/mastors-core.css --style expanded --source-map --load-path=node_modules",
|
|
68
|
+
"sass:min": "sass scss/mastors-core.scss dist/mastors-core.min.css --style compressed --no-source-map --load-path=node_modules",
|
|
69
|
+
"sass:watch": "sass --watch scss/mastors-core.scss:dist/mastors-core.css --style expanded --source-map --load-path=node_modules",
|
|
70
|
+
"sass:all": "npm run sass:build && npm run sass:min",
|
|
71
|
+
"build:all": "npm run sass:all && npm run build",
|
|
72
|
+
"clean": "rimraf dist",
|
|
73
|
+
"prebuild": "npm run clean",
|
|
61
74
|
"prepublishOnly": "npm run sass:all"
|
|
62
75
|
},
|
|
63
76
|
"devDependencies": {
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
77
|
+
"rimraf": "^5.0.0",
|
|
78
|
+
"sass": "^1.77.0",
|
|
79
|
+
"vite": "^5.3.0"
|
|
67
80
|
},
|
|
68
81
|
"peerDependencies": {
|
|
69
82
|
"sass": ">=1.70.0"
|
|
@@ -73,10 +86,10 @@
|
|
|
73
86
|
},
|
|
74
87
|
"repository": {
|
|
75
88
|
"type": "git",
|
|
76
|
-
"url":
|
|
89
|
+
"url": "git+https://github.com/KEHEM-IT/Mastors-Core.git"
|
|
77
90
|
},
|
|
78
91
|
"bugs": {
|
|
79
92
|
"url": "https://github.com/KEHEM-IT/Mastors-Core/issues"
|
|
80
93
|
},
|
|
81
|
-
"homepage": "https://mastorscdn.kehem.com/
|
|
82
|
-
}
|
|
94
|
+
"homepage": "https://mastorscdn.kehem.com/"
|
|
95
|
+
}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// Mastors-Core | postinstall.js
|
|
4
|
+
// Runs after `npm install @mastorscdn/core`
|
|
5
|
+
// Auto-detects the user's framework and prints the exact setup guide.
|
|
6
|
+
// =============================================================================
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
// ── ANSI colours ─────────────────────────────────────────────────────────────
|
|
14
|
+
const C = {
|
|
15
|
+
reset: '\x1b[0m',
|
|
16
|
+
bold: '\x1b[1m',
|
|
17
|
+
cyan: '\x1b[36m',
|
|
18
|
+
green: '\x1b[32m',
|
|
19
|
+
yellow: '\x1b[33m',
|
|
20
|
+
magenta: '\x1b[35m',
|
|
21
|
+
gray: '\x1b[90m',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const b = (s) => `${C.bold}${s}${C.reset}`;
|
|
25
|
+
const c = (s) => `${C.cyan}${s}${C.reset}`;
|
|
26
|
+
const g = (s) => `${C.green}${s}${C.reset}`;
|
|
27
|
+
const y = (s) => `${C.yellow}${s}${C.reset}`;
|
|
28
|
+
const m = (s) => `${C.magenta}${s}${C.reset}`;
|
|
29
|
+
const gr = (s) => `${C.gray}${s}${C.reset}`;
|
|
30
|
+
|
|
31
|
+
// ── Resolve user's project root ───────────────────────────────────────────────
|
|
32
|
+
// When installed as a dep, __dirname = .../node_modules/@mastorscdn/core/scripts
|
|
33
|
+
// So root is several levels up from here.
|
|
34
|
+
function findProjectRoot() {
|
|
35
|
+
let dir = __dirname;
|
|
36
|
+
for (let i = 0; i < 6; i++) {
|
|
37
|
+
const pkg = path.join(dir, 'package.json');
|
|
38
|
+
if (fs.existsSync(pkg)) {
|
|
39
|
+
try {
|
|
40
|
+
const p = JSON.parse(fs.readFileSync(pkg, 'utf8'));
|
|
41
|
+
if (p.name !== '@mastorscdn/core') return dir;
|
|
42
|
+
} catch (_) {}
|
|
43
|
+
}
|
|
44
|
+
const parent = path.dirname(dir);
|
|
45
|
+
if (parent === dir) break;
|
|
46
|
+
dir = parent;
|
|
47
|
+
}
|
|
48
|
+
return process.cwd();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const ROOT = findProjectRoot();
|
|
52
|
+
|
|
53
|
+
function getUserPkg() {
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
|
|
56
|
+
} catch (_) {
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ── Framework detection ───────────────────────────────────────────────────────
|
|
62
|
+
function detectFramework(pkg) {
|
|
63
|
+
const all = {
|
|
64
|
+
...pkg.dependencies,
|
|
65
|
+
...pkg.devDependencies,
|
|
66
|
+
...pkg.peerDependencies,
|
|
67
|
+
};
|
|
68
|
+
const has = (name) => Boolean(all[name]);
|
|
69
|
+
|
|
70
|
+
if (has('next')) return 'next';
|
|
71
|
+
if (has('nuxt') || has('@nuxt/ui')) return 'nuxt';
|
|
72
|
+
if (has('astro') || has('@astrojs/react')) return 'astro';
|
|
73
|
+
if (has('@sveltejs/kit')) return 'sveltekit';
|
|
74
|
+
if (has('svelte')) return 'svelte';
|
|
75
|
+
if (has('@remix-run/react') || has('@remix-run/node')) return 'remix';
|
|
76
|
+
if (has('vite') && has('vue')) return 'vite-vue';
|
|
77
|
+
if (has('vite') && has('react')) return 'vite-react';
|
|
78
|
+
if (has('vite')) return 'vite';
|
|
79
|
+
if (has('vue')) return 'vue-cli';
|
|
80
|
+
if (has('@angular/core')) return 'angular';
|
|
81
|
+
if (has('react')) return 'react';
|
|
82
|
+
return 'node';
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ── Banner ────────────────────────────────────────────────────────────────────
|
|
86
|
+
function banner() {
|
|
87
|
+
console.log('');
|
|
88
|
+
console.log(b(c(' ╔══════════════════════════════════════════╗')));
|
|
89
|
+
console.log(b(c(' ║ @mastorscdn/core installed! ║')));
|
|
90
|
+
console.log(b(c(' ╚══════════════════════════════════════════╝')));
|
|
91
|
+
console.log('');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ── Guides ────────────────────────────────────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
function guideNode() {
|
|
97
|
+
console.log(b(g(' ✔ Plain Node + Sass')));
|
|
98
|
+
console.log('');
|
|
99
|
+
console.log(' Run sass with --load-path:');
|
|
100
|
+
console.log('');
|
|
101
|
+
console.log(c(' sass --watch src/main.scss:dist/main.css --load-path=node_modules'));
|
|
102
|
+
console.log('');
|
|
103
|
+
console.log(' Or add to your package.json scripts:');
|
|
104
|
+
console.log('');
|
|
105
|
+
console.log(gr(' "sass:watch": "sass --watch src/main.scss:dist/main.css --load-path=node_modules"'));
|
|
106
|
+
console.log('');
|
|
107
|
+
console.log(' Then in your SCSS:');
|
|
108
|
+
console.log(m(" @use '@mastorscdn/core' as mc;"));
|
|
109
|
+
console.log('');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function guideNext() {
|
|
113
|
+
console.log(b(g(' ✔ Next.js detected')));
|
|
114
|
+
console.log('');
|
|
115
|
+
console.log(' Add to ' + c('next.config.mjs') + ':');
|
|
116
|
+
console.log('');
|
|
117
|
+
console.log(gr(" const nextConfig = {"));
|
|
118
|
+
console.log(gr(" sassOptions: { loadPaths: ['./node_modules'] },"));
|
|
119
|
+
console.log(gr(" };"));
|
|
120
|
+
console.log(gr(" export default nextConfig;"));
|
|
121
|
+
console.log('');
|
|
122
|
+
console.log(' Import in ' + c('app/layout.tsx') + ' or ' + c('pages/_app.js') + ':');
|
|
123
|
+
console.log(gr(" import '../styles/globals.scss';"));
|
|
124
|
+
console.log('');
|
|
125
|
+
console.log(' In globals.scss:');
|
|
126
|
+
console.log(m(" @use '@mastorscdn/core' as mc;"));
|
|
127
|
+
console.log('');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function guideVite(flavour) {
|
|
131
|
+
const label = { 'vite-vue': 'Vite + Vue', 'vite-react': 'Vite + React', 'vite': 'Vite' }[flavour] || 'Vite';
|
|
132
|
+
console.log(b(g(` ✔ ${label} detected`)));
|
|
133
|
+
console.log('');
|
|
134
|
+
console.log(' Add to ' + c('vite.config.js') + ':');
|
|
135
|
+
console.log('');
|
|
136
|
+
console.log(gr(" import path from 'path';"));
|
|
137
|
+
console.log(gr(" export default defineConfig({"));
|
|
138
|
+
console.log(gr(" css: {"));
|
|
139
|
+
console.log(gr(" preprocessorOptions: {"));
|
|
140
|
+
console.log(gr(" scss: {"));
|
|
141
|
+
console.log(gr(" api: 'modern-compiler',"));
|
|
142
|
+
console.log(gr(" loadPaths: [path.resolve(__dirname, 'node_modules')],"));
|
|
143
|
+
console.log(gr(" },"));
|
|
144
|
+
console.log(gr(" },"));
|
|
145
|
+
console.log(gr(" },"));
|
|
146
|
+
console.log(gr(" });"));
|
|
147
|
+
console.log('');
|
|
148
|
+
console.log(m(" @use '@mastorscdn/core' as mc;"));
|
|
149
|
+
console.log('');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function guideNuxt() {
|
|
153
|
+
console.log(b(g(' ✔ Nuxt detected')));
|
|
154
|
+
console.log('');
|
|
155
|
+
console.log(' Add to ' + c('nuxt.config.ts') + ':');
|
|
156
|
+
console.log('');
|
|
157
|
+
console.log(gr(" export default defineNuxtConfig({"));
|
|
158
|
+
console.log(gr(" vite: {"));
|
|
159
|
+
console.log(gr(" css: {"));
|
|
160
|
+
console.log(gr(" preprocessorOptions: {"));
|
|
161
|
+
console.log(gr(" scss: {"));
|
|
162
|
+
console.log(gr(" api: 'modern-compiler',"));
|
|
163
|
+
console.log(gr(" loadPaths: ['./node_modules'],"));
|
|
164
|
+
console.log(gr(" },"));
|
|
165
|
+
console.log(gr(" },"));
|
|
166
|
+
console.log(gr(" },"));
|
|
167
|
+
console.log(gr(" },"));
|
|
168
|
+
console.log(gr(" });"));
|
|
169
|
+
console.log('');
|
|
170
|
+
console.log(m(" @use '@mastorscdn/core' as mc;"));
|
|
171
|
+
console.log('');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function guideAstro() {
|
|
175
|
+
console.log(b(g(' ✔ Astro detected')));
|
|
176
|
+
console.log('');
|
|
177
|
+
console.log(' Add to ' + c('astro.config.mjs') + ':');
|
|
178
|
+
console.log('');
|
|
179
|
+
console.log(gr(" import path from 'path';"));
|
|
180
|
+
console.log(gr(" export default defineConfig({"));
|
|
181
|
+
console.log(gr(" vite: {"));
|
|
182
|
+
console.log(gr(" css: { preprocessorOptions: { scss: {"));
|
|
183
|
+
console.log(gr(" api: 'modern-compiler',"));
|
|
184
|
+
console.log(gr(" loadPaths: [path.resolve('./node_modules')],"));
|
|
185
|
+
console.log(gr(" } } },"));
|
|
186
|
+
console.log(gr(" },"));
|
|
187
|
+
console.log(gr(" });"));
|
|
188
|
+
console.log('');
|
|
189
|
+
console.log(m(" @use '@mastorscdn/core' as mc;"));
|
|
190
|
+
console.log('');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function guideSvelteKit() {
|
|
194
|
+
console.log(b(g(' ✔ SvelteKit detected')));
|
|
195
|
+
console.log('');
|
|
196
|
+
console.log(' Add to ' + c('vite.config.js') + ':');
|
|
197
|
+
console.log('');
|
|
198
|
+
console.log(gr(" import path from 'path';"));
|
|
199
|
+
console.log(gr(" export default { plugins: [sveltekit()],"));
|
|
200
|
+
console.log(gr(" css: { preprocessorOptions: { scss: {"));
|
|
201
|
+
console.log(gr(" api: 'modern-compiler',"));
|
|
202
|
+
console.log(gr(" loadPaths: [path.resolve('./node_modules')],"));
|
|
203
|
+
console.log(gr(" } } },"));
|
|
204
|
+
console.log(gr(" };"));
|
|
205
|
+
console.log('');
|
|
206
|
+
console.log(m(" @use '@mastorscdn/core' as mc;"));
|
|
207
|
+
console.log('');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function guideRemix() {
|
|
211
|
+
console.log(b(g(' ✔ Remix detected')));
|
|
212
|
+
console.log('');
|
|
213
|
+
console.log(' Add to ' + c('vite.config.ts') + ' css section:');
|
|
214
|
+
console.log('');
|
|
215
|
+
console.log(gr(" css: { preprocessorOptions: { scss: {"));
|
|
216
|
+
console.log(gr(" api: 'modern-compiler',"));
|
|
217
|
+
console.log(gr(" loadPaths: ['./node_modules'],"));
|
|
218
|
+
console.log(gr(" } } },"));
|
|
219
|
+
console.log('');
|
|
220
|
+
console.log(m(" @use '@mastorscdn/core' as mc;"));
|
|
221
|
+
console.log('');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function guideAngular() {
|
|
225
|
+
console.log(b(g(' ✔ Angular detected')));
|
|
226
|
+
console.log('');
|
|
227
|
+
console.log(' In ' + c('angular.json') + ' under build > options:');
|
|
228
|
+
console.log('');
|
|
229
|
+
console.log(gr(' "stylePreprocessorOptions": {'));
|
|
230
|
+
console.log(gr(' "includePaths": ["node_modules"]'));
|
|
231
|
+
console.log(gr(' }'));
|
|
232
|
+
console.log('');
|
|
233
|
+
console.log(m(" @use '@mastorscdn/core' as mc;"));
|
|
234
|
+
console.log('');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ── Write mc.config.js ────────────────────────────────────────────────────────
|
|
238
|
+
function writeMcConfig(framework) {
|
|
239
|
+
const configPath = path.join(ROOT, 'mc.config.js');
|
|
240
|
+
if (fs.existsSync(configPath)) return;
|
|
241
|
+
|
|
242
|
+
const content = `// =============================================================================
|
|
243
|
+
// mc.config.js — Mastors Core Configuration Reference
|
|
244
|
+
// Auto-generated by @mastorscdn/core on install
|
|
245
|
+
// Detected framework: ${framework}
|
|
246
|
+
//
|
|
247
|
+
// Copy the relevant snippet from this file into your bundler config.
|
|
248
|
+
// Full docs: https://mastorscdn.kehem.com/
|
|
249
|
+
// =============================================================================
|
|
250
|
+
|
|
251
|
+
/** @type {import('@mastorscdn/core').McConfig} */
|
|
252
|
+
const mcConfig = {
|
|
253
|
+
// Add to your bundler's scss preprocessorOptions:
|
|
254
|
+
loadPaths: ['./node_modules'],
|
|
255
|
+
|
|
256
|
+
// Override Mastors tokens in SCSS:
|
|
257
|
+
// @use '@mastorscdn/core' with (
|
|
258
|
+
// $enable-dark-theme: true,
|
|
259
|
+
// $enable-utilities: true,
|
|
260
|
+
// $mastors-prefix: 'mc',
|
|
261
|
+
// );
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
module.exports = mcConfig;
|
|
265
|
+
`;
|
|
266
|
+
|
|
267
|
+
try { fs.writeFileSync(configPath, content, 'utf8'); } catch (_) {}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// ── Footer ────────────────────────────────────────────────────────────────────
|
|
271
|
+
function footer(framework) {
|
|
272
|
+
console.log(b(' ─────────────────────────────────────────────'));
|
|
273
|
+
console.log('');
|
|
274
|
+
console.log(' ' + b('In any .scss file:'));
|
|
275
|
+
console.log('');
|
|
276
|
+
console.log(m(" @use '@mastorscdn/core' as mc;"));
|
|
277
|
+
console.log('');
|
|
278
|
+
console.log(gr(' .card {'));
|
|
279
|
+
console.log(gr(" color: mc.color('primary');"));
|
|
280
|
+
console.log(gr(" border-radius: mc.radius('lg');"));
|
|
281
|
+
console.log(gr(" box-shadow: mc.shadow('md');"));
|
|
282
|
+
console.log(gr(" @include mc.up('md') { padding: 2rem; }"));
|
|
283
|
+
console.log(gr(' }'));
|
|
284
|
+
console.log('');
|
|
285
|
+
console.log(' ' + b('Docs:') + ' ' + c('https://mastorscdn.kehem.com/'));
|
|
286
|
+
console.log(' ' + b('npm:') + ' ' + c('https://www.npmjs.com/package/@mastorscdn/core'));
|
|
287
|
+
console.log('');
|
|
288
|
+
if (framework !== 'node') {
|
|
289
|
+
console.log(' ' + y('📄 mc.config.js written to your project root.'));
|
|
290
|
+
console.log('');
|
|
291
|
+
}
|
|
292
|
+
console.log(b(c(' Happy styling with Mastors Core! 🚀')));
|
|
293
|
+
console.log('');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ── Main ──────────────────────────────────────────────────────────────────────
|
|
297
|
+
function main() {
|
|
298
|
+
if (process.env.CI && process.env.MASTORS_SILENT) return;
|
|
299
|
+
|
|
300
|
+
const pkg = getUserPkg();
|
|
301
|
+
const framework = detectFramework(pkg);
|
|
302
|
+
|
|
303
|
+
banner();
|
|
304
|
+
console.log(` ${b('Detected environment:')} ${g(framework)}`);
|
|
305
|
+
console.log('');
|
|
306
|
+
|
|
307
|
+
switch (framework) {
|
|
308
|
+
case 'next': guideNext(); break;
|
|
309
|
+
case 'nuxt': guideNuxt(); break;
|
|
310
|
+
case 'astro': guideAstro(); break;
|
|
311
|
+
case 'sveltekit':
|
|
312
|
+
case 'svelte': guideSvelteKit(); break;
|
|
313
|
+
case 'remix': guideRemix(); break;
|
|
314
|
+
case 'vite-vue': guideVite('vite-vue'); break;
|
|
315
|
+
case 'vite-react': guideVite('vite-react'); break;
|
|
316
|
+
case 'vite': guideVite('vite'); break;
|
|
317
|
+
case 'angular': guideAngular(); break;
|
|
318
|
+
default: guideNode(); break;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (framework !== 'node') writeMcConfig(framework);
|
|
322
|
+
footer(framework);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
main();
|