@pure-ds/core 0.3.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.
- package/CSS-INTELLISENSE-LIMITATION.md +98 -0
- package/CSS-INTELLISENSE-QUICK-REF.md +238 -0
- package/INTELLISENSE.md +384 -0
- package/LICENSE +15 -0
- package/custom-elements-manifest.config.js +30 -0
- package/custom-elements.json +2003 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/packages/pds-configurator/src/figma-export.d.ts +13 -0
- package/dist/types/packages/pds-configurator/src/figma-export.d.ts.map +1 -0
- package/dist/types/packages/pds-configurator/src/pds-config-form.d.ts +2 -0
- package/dist/types/packages/pds-configurator/src/pds-config-form.d.ts.map +1 -0
- package/dist/types/packages/pds-configurator/src/pds-configurator.d.ts +2 -0
- package/dist/types/packages/pds-configurator/src/pds-configurator.d.ts.map +1 -0
- package/dist/types/packages/pds-configurator/src/pds-demo.d.ts +2 -0
- package/dist/types/packages/pds-configurator/src/pds-demo.d.ts.map +1 -0
- package/dist/types/pds.config.d.ts +13 -0
- package/dist/types/pds.config.d.ts.map +1 -0
- package/dist/types/pds.d.ts +408 -0
- package/dist/types/public/assets/js/app.d.ts +2 -0
- package/dist/types/public/assets/js/app.d.ts.map +1 -0
- package/dist/types/public/assets/js/pds.d.ts +23 -0
- package/dist/types/public/assets/js/pds.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-calendar.d.ts +23 -0
- package/dist/types/public/assets/pds/components/pds-calendar.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-drawer.d.ts +2 -0
- package/dist/types/public/assets/pds/components/pds-drawer.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-icon.d.ts +53 -0
- package/dist/types/public/assets/pds/components/pds-icon.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-jsonform.d.ts +104 -0
- package/dist/types/public/assets/pds/components/pds-jsonform.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-richtext.d.ts +121 -0
- package/dist/types/public/assets/pds/components/pds-richtext.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-scrollrow.d.ts +61 -0
- package/dist/types/public/assets/pds/components/pds-scrollrow.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-splitpanel.d.ts +1 -0
- package/dist/types/public/assets/pds/components/pds-splitpanel.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-tabstrip.d.ts +39 -0
- package/dist/types/public/assets/pds/components/pds-tabstrip.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-toaster.d.ts +111 -0
- package/dist/types/public/assets/pds/components/pds-toaster.d.ts.map +1 -0
- package/dist/types/public/assets/pds/components/pds-upload.d.ts +83 -0
- package/dist/types/public/assets/pds/components/pds-upload.d.ts.map +1 -0
- package/dist/types/src/js/app.d.ts +2 -0
- package/dist/types/src/js/app.d.ts.map +1 -0
- package/dist/types/src/js/common/ask.d.ts +22 -0
- package/dist/types/src/js/common/ask.d.ts.map +1 -0
- package/dist/types/src/js/common/common.d.ts +3 -0
- package/dist/types/src/js/common/common.d.ts.map +1 -0
- package/dist/types/src/js/common/font-loader.d.ts +24 -0
- package/dist/types/src/js/common/font-loader.d.ts.map +1 -0
- package/dist/types/src/js/common/msg.d.ts +3 -0
- package/dist/types/src/js/common/msg.d.ts.map +1 -0
- package/dist/types/src/js/lit.d.ts +25 -0
- package/dist/types/src/js/lit.d.ts.map +1 -0
- package/dist/types/src/js/pds-configurator/figma-export.d.ts +13 -0
- package/dist/types/src/js/pds-configurator/figma-export.d.ts.map +1 -0
- package/dist/types/src/js/pds-configurator/pds-config-form.d.ts +2 -0
- package/dist/types/src/js/pds-configurator/pds-config-form.d.ts.map +1 -0
- package/dist/types/src/js/pds-configurator/pds-configurator.d.ts +2 -0
- package/dist/types/src/js/pds-configurator/pds-configurator.d.ts.map +1 -0
- package/dist/types/src/js/pds-configurator/pds-demo.d.ts +2 -0
- package/dist/types/src/js/pds-configurator/pds-demo.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-config.d.ts +758 -0
- package/dist/types/src/js/pds-core/pds-config.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-enhancer-metadata.d.ts +6 -0
- package/dist/types/src/js/pds-core/pds-enhancer-metadata.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-enhancers.d.ts +14 -0
- package/dist/types/src/js/pds-core/pds-enhancers.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-enums.d.ts +87 -0
- package/dist/types/src/js/pds-core/pds-enums.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-generator.d.ts +741 -0
- package/dist/types/src/js/pds-core/pds-generator.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-ontology.d.ts +48 -0
- package/dist/types/src/js/pds-core/pds-ontology.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-paths.d.ts +37 -0
- package/dist/types/src/js/pds-core/pds-paths.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-query.d.ts +102 -0
- package/dist/types/src/js/pds-core/pds-query.d.ts.map +1 -0
- package/dist/types/src/js/pds-core/pds-registry.d.ts +40 -0
- package/dist/types/src/js/pds-core/pds-registry.d.ts.map +1 -0
- package/dist/types/src/js/pds.d.ts +109 -0
- package/dist/types/src/js/pds.d.ts.map +1 -0
- package/dist/types/src/pds-core/pds-api.d.ts +31 -0
- package/dist/types/src/pds-core/pds-api.d.ts.map +1 -0
- package/package.json +104 -0
- package/packages/pds-cli/README.md +15 -0
- package/packages/pds-cli/bin/generate-css-data.js +565 -0
- package/packages/pds-cli/bin/generate-manifest.js +352 -0
- package/packages/pds-cli/bin/pds-build-icons.js +152 -0
- package/packages/pds-cli/bin/pds-dx.js +114 -0
- package/packages/pds-cli/bin/pds-static.js +556 -0
- package/packages/pds-cli/bin/pds.js +127 -0
- package/packages/pds-cli/bin/postinstall.js +380 -0
- package/packages/pds-cli/bin/sync-assets.js +252 -0
- package/packages/pds-cli/lib/asset-roots.js +47 -0
- package/packages/pds-cli/lib/fs-writer.js +75 -0
- package/pds.css-data.json +5 -0
- package/pds.html-data.json +5 -0
- package/public/assets/js/app.js +5719 -0
- package/public/assets/js/lit.js +131 -0
- package/public/assets/js/pds.js +3423 -0
- package/public/assets/pds/components/pds-calendar.js +837 -0
- package/public/assets/pds/components/pds-drawer.js +857 -0
- package/public/assets/pds/components/pds-icon.js +338 -0
- package/public/assets/pds/components/pds-jsonform.js +1775 -0
- package/public/assets/pds/components/pds-richtext.js +1035 -0
- package/public/assets/pds/components/pds-scrollrow.js +331 -0
- package/public/assets/pds/components/pds-splitpanel.js +401 -0
- package/public/assets/pds/components/pds-tabstrip.js +251 -0
- package/public/assets/pds/components/pds-toaster.js +446 -0
- package/public/assets/pds/components/pds-upload.js +657 -0
- package/public/assets/pds/custom-elements.json +2003 -0
- package/public/assets/pds/icons/pds-icons.svg +498 -0
- package/public/assets/pds/pds-css-complete.json +1861 -0
- package/public/assets/pds/pds.css-data.json +2152 -0
- package/public/assets/pds/vscode-custom-data.json +824 -0
- package/readme.md +1870 -0
- package/src/js/pds-core/pds-config.js +1162 -0
- package/src/js/pds-core/pds-enhancer-metadata.js +75 -0
- package/src/js/pds-core/pds-enhancers.js +357 -0
- package/src/js/pds-core/pds-enums.js +86 -0
- package/src/js/pds-core/pds-generator.js +5317 -0
- package/src/js/pds-core/pds-ontology.js +256 -0
- package/src/js/pds-core/pds-paths.js +109 -0
- package/src/js/pds-core/pds-query.js +571 -0
- package/src/js/pds-core/pds-registry.js +129 -0
- package/src/js/pds-core/pds.d.ts +129 -0
- package/src/js/pds.d.ts +408 -0
- package/src/js/pds.js +1579 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* NPM postinstall script for @pure-ds/core
|
|
5
|
+
* Automatically copies PDS assets to the consuming app's web root
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFile, writeFile, mkdir, copyFile, readdir, stat, access, unlink } from 'fs/promises';
|
|
9
|
+
import { readFileSync } from 'fs';
|
|
10
|
+
import { createHash } from 'crypto';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
13
|
+
|
|
14
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const repoRoot = path.resolve(__dirname, '../../../');
|
|
16
|
+
const isWin = process.platform === 'win32';
|
|
17
|
+
const normalizePath = (p) => {
|
|
18
|
+
if (!p) return '';
|
|
19
|
+
const resolved = path.resolve(p).replace(/[\\/]+$/, '');
|
|
20
|
+
return isWin ? resolved.toLowerCase() : resolved;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Check if we're installing within the @pure-ds/core repo itself (not a consumer)
|
|
25
|
+
*/
|
|
26
|
+
function isInstallingWithinPureDsRepo() {
|
|
27
|
+
try {
|
|
28
|
+
const cwd = process.cwd();
|
|
29
|
+
const initCwd = process.env.INIT_CWD || cwd;
|
|
30
|
+
|
|
31
|
+
// Check if the INIT_CWD has package.json with name "@pure-ds/core"
|
|
32
|
+
// This is more reliable than path comparison since repoRoot
|
|
33
|
+
// points to node_modules/@pure-ds/core when installed as a dependency
|
|
34
|
+
try {
|
|
35
|
+
const pkgPath = path.join(initCwd, 'package.json');
|
|
36
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
37
|
+
return pkg.name === '@pure-ds/core' || pkg.name === 'pure-ds';
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
} catch (err) {
|
|
42
|
+
console.log('⚠️ Error checking repo location:', err.message);
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isNpmLinkInvocation() {
|
|
48
|
+
const truthy = (value) => {
|
|
49
|
+
if (value === undefined || value === null) return false;
|
|
50
|
+
const normalized = String(value).toLowerCase();
|
|
51
|
+
return normalized === 'true' || normalized === '1';
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
if (truthy(process.env.npm_config_link)) return true;
|
|
55
|
+
if ((process.env.npm_command || '').toLowerCase() === 'link') return true;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const argvRaw = process.env.npm_config_argv;
|
|
59
|
+
if (!argvRaw) return false;
|
|
60
|
+
const argv = JSON.parse(argvRaw);
|
|
61
|
+
const orig = argv && (argv.original || argv.cooked || []);
|
|
62
|
+
if (!Array.isArray(orig)) return false;
|
|
63
|
+
return orig.includes('link');
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function isLinkedPackagePath(p) {
|
|
70
|
+
return !/[\\/]+node_modules[\\/]+/i.test(p);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function isGlobalInstall() {
|
|
74
|
+
const value = process.env.npm_config_global;
|
|
75
|
+
if (!value) return false;
|
|
76
|
+
const normalized = String(value).toLowerCase();
|
|
77
|
+
return normalized === 'true' || normalized === '1';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Find the consumer app root (directory containing the consumer's package.json)
|
|
82
|
+
* Prefer INIT_CWD (npm sets this to the original cwd) and fallback by walking up from the package dir
|
|
83
|
+
*/
|
|
84
|
+
async function findConsumerRoot() {
|
|
85
|
+
const tryPaths = [];
|
|
86
|
+
if (process.env.INIT_CWD) tryPaths.push(process.env.INIT_CWD);
|
|
87
|
+
// Walk up from the package dir until we exit node_modules
|
|
88
|
+
let dir = repoRoot;
|
|
89
|
+
while (dir && path.basename(dir) !== path.dirname(dir)) {
|
|
90
|
+
if (path.basename(dir) === 'node_modules') {
|
|
91
|
+
const candidate = path.dirname(dir);
|
|
92
|
+
tryPaths.push(candidate);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
dir = path.dirname(dir);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (const p of tryPaths) {
|
|
99
|
+
try {
|
|
100
|
+
const pkgPath = path.join(p, 'package.json');
|
|
101
|
+
const pkg = JSON.parse(await readFile(pkgPath, 'utf8'));
|
|
102
|
+
if (pkg && pkg.name && pkg.name !== 'pure-ds') {
|
|
103
|
+
return p;
|
|
104
|
+
}
|
|
105
|
+
} catch {}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Final fallback: INIT_CWD or current working dir
|
|
109
|
+
return process.env.INIT_CWD || process.cwd();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Ensure consumer package.json contains a handy export script
|
|
114
|
+
*/
|
|
115
|
+
async function ensureExportScript(consumerRoot) {
|
|
116
|
+
try {
|
|
117
|
+
const consumerPkgPath = path.join(consumerRoot, 'package.json');
|
|
118
|
+
const consumerPkgRaw = await readFile(consumerPkgPath, 'utf8');
|
|
119
|
+
const consumerPkg = JSON.parse(consumerPkgRaw);
|
|
120
|
+
|
|
121
|
+
consumerPkg.scripts = consumerPkg.scripts || {};
|
|
122
|
+
|
|
123
|
+
const desiredScriptName = 'pds:export';
|
|
124
|
+
const desiredScriptCmd = 'pds-export';
|
|
125
|
+
|
|
126
|
+
if (!consumerPkg.scripts[desiredScriptName]) {
|
|
127
|
+
consumerPkg.scripts[desiredScriptName] = desiredScriptCmd;
|
|
128
|
+
await writeFile(consumerPkgPath, JSON.stringify(consumerPkg, null, 2) + '\n');
|
|
129
|
+
console.log(`🧩 Added "${desiredScriptName}" script to consumer package.json`);
|
|
130
|
+
} else {
|
|
131
|
+
console.log(`🔧 Script "${desiredScriptName}" already present in consumer package.json`);
|
|
132
|
+
}
|
|
133
|
+
} catch (e) {
|
|
134
|
+
console.warn('⚠️ Could not ensure pds:export script in consumer package.json:', e.message);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Discover the web root directory using common patterns
|
|
140
|
+
*/
|
|
141
|
+
async function discoverWebRoot(baseDir) {
|
|
142
|
+
const cwd = baseDir || process.env.INIT_CWD || process.cwd();
|
|
143
|
+
|
|
144
|
+
// Common web root patterns (in order of preference)
|
|
145
|
+
const candidates = [
|
|
146
|
+
'public',
|
|
147
|
+
'static',
|
|
148
|
+
'dist',
|
|
149
|
+
'build',
|
|
150
|
+
'www',
|
|
151
|
+
'web',
|
|
152
|
+
'assets',
|
|
153
|
+
'src/assets',
|
|
154
|
+
'app/public',
|
|
155
|
+
'.' // fallback to current directory
|
|
156
|
+
];
|
|
157
|
+
|
|
158
|
+
console.log('🔍 Discovering web root directory...');
|
|
159
|
+
|
|
160
|
+
for (const candidate of candidates) {
|
|
161
|
+
const fullPath = path.resolve(cwd, candidate);
|
|
162
|
+
try {
|
|
163
|
+
await access(fullPath);
|
|
164
|
+
const stats = await stat(fullPath);
|
|
165
|
+
if (stats.isDirectory()) {
|
|
166
|
+
console.log(` ✅ Found: ${candidate}/`);
|
|
167
|
+
return { path: fullPath, relative: candidate };
|
|
168
|
+
}
|
|
169
|
+
} catch (e) {
|
|
170
|
+
// Directory doesn't exist, continue
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Check package.json for hints
|
|
175
|
+
try {
|
|
176
|
+
const packagePath = path.join(cwd, 'package.json');
|
|
177
|
+
const pkg = JSON.parse(await readFile(packagePath, 'utf8'));
|
|
178
|
+
|
|
179
|
+
// Look for common build/output directories in scripts
|
|
180
|
+
const scripts = pkg.scripts || {};
|
|
181
|
+
const scriptText = JSON.stringify(scripts);
|
|
182
|
+
|
|
183
|
+
if (scriptText.includes('--outdir dist') || scriptText.includes('dist/')) {
|
|
184
|
+
const distPath = path.resolve(cwd, 'dist');
|
|
185
|
+
console.log(` 💡 Found "dist" in scripts, using: dist/`);
|
|
186
|
+
return { path: distPath, relative: 'dist' };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (scriptText.includes('--outdir build') || scriptText.includes('build/')) {
|
|
190
|
+
const buildPath = path.resolve(cwd, 'build');
|
|
191
|
+
console.log(` 💡 Found "build" in scripts, using: build/`);
|
|
192
|
+
return { path: buildPath, relative: 'build' };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Check for common framework configs
|
|
196
|
+
if (pkg.dependencies?.['next'] || pkg.devDependencies?.['next']) {
|
|
197
|
+
const publicPath = path.resolve(cwd, 'public');
|
|
198
|
+
console.log(` 🔧 Next.js detected, using: public/`);
|
|
199
|
+
return { path: publicPath, relative: 'public' };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (pkg.dependencies?.['vite'] || pkg.devDependencies?.['vite']) {
|
|
203
|
+
const publicPath = path.resolve(cwd, 'public');
|
|
204
|
+
console.log(` ⚡ Vite detected, using: public/`);
|
|
205
|
+
return { path: publicPath, relative: 'public' };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
} catch (e) {
|
|
209
|
+
// No package.json or parsing failed
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Ultimate fallback: create public directory
|
|
213
|
+
const fallbackPath = path.resolve(cwd, 'public');
|
|
214
|
+
console.log(` 📁 Creating fallback: public/`);
|
|
215
|
+
await mkdir(fallbackPath, { recursive: true });
|
|
216
|
+
return { path: fallbackPath, relative: 'public' };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Copy PDS assets to the discovered web root
|
|
221
|
+
*/
|
|
222
|
+
async function copyPdsAssets() {
|
|
223
|
+
console.log('📦 PDS postinstall running (no automatic component copy)…');
|
|
224
|
+
try {
|
|
225
|
+
const normalizedRepoRoot = normalizePath(repoRoot);
|
|
226
|
+
const normalizedInitCwd = normalizePath(process.env.INIT_CWD || process.cwd());
|
|
227
|
+
|
|
228
|
+
if (isLinkedPackagePath(normalizedRepoRoot)) {
|
|
229
|
+
console.log('🛑 Skipping PDS postinstall (detected symlinked package path).');
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (normalizedInitCwd === normalizedRepoRoot) {
|
|
234
|
+
console.log('🛑 Skipping PDS postinstall (working inside pure-ds repository root).');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (isNpmLinkInvocation()) {
|
|
239
|
+
console.log('🛑 Skipping PDS postinstall (detected npm link invocation).');
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (isGlobalInstall()) {
|
|
244
|
+
console.log('🛑 Skipping PDS postinstall (global install detected).');
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const consumerRoot = await findConsumerRoot();
|
|
249
|
+
console.log('🧪 Consumer root:', consumerRoot);
|
|
250
|
+
|
|
251
|
+
// Allow opting out explicitly (useful for local dev / linking)
|
|
252
|
+
if (
|
|
253
|
+
process.env.PDS_SKIP_POSTINSTALL === '1' ||
|
|
254
|
+
process.env.PDS_SKIP_POSTINSTALL === 'true' ||
|
|
255
|
+
process.env.npm_config_pds_skip_postinstall === 'true'
|
|
256
|
+
) {
|
|
257
|
+
console.log('⏭️ Skipping PDS postinstall (PDS_SKIP_POSTINSTALL set).');
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// If running inside the package repo itself (e.g., during `npm link`), skip
|
|
262
|
+
const inRepo = normalizePath(consumerRoot) === normalizePath(repoRoot);
|
|
263
|
+
const withinPureDs = isInstallingWithinPureDsRepo();
|
|
264
|
+
|
|
265
|
+
if (inRepo || withinPureDs) {
|
|
266
|
+
let reason = 'installing within pure-ds repository';
|
|
267
|
+
if (inRepo) {
|
|
268
|
+
reason = 'inside the package repo';
|
|
269
|
+
} else if (withinPureDs) {
|
|
270
|
+
reason = 'installing within pure-ds repository';
|
|
271
|
+
}
|
|
272
|
+
console.log(`🛑 Skipping PDS postinstall (${reason}).`);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
console.log('📦 Proceeding with asset copying...');
|
|
277
|
+
|
|
278
|
+
// Proactively add export & build-icons scripts to consumer package.json (still helpful)
|
|
279
|
+
await ensureExportScript(consumerRoot);
|
|
280
|
+
try {
|
|
281
|
+
const consumerPkgPath = path.join(consumerRoot, 'package.json');
|
|
282
|
+
const pkgRaw = await readFile(consumerPkgPath, 'utf8');
|
|
283
|
+
const pkgJson = JSON.parse(pkgRaw);
|
|
284
|
+
pkgJson.scripts = pkgJson.scripts || {};
|
|
285
|
+
const buildIconsName = 'pds:build-icons';
|
|
286
|
+
const buildIconsCmd = 'pds-build-icons';
|
|
287
|
+
if (!pkgJson.scripts[buildIconsName]) {
|
|
288
|
+
pkgJson.scripts[buildIconsName] = buildIconsCmd;
|
|
289
|
+
await writeFile(consumerPkgPath, JSON.stringify(pkgJson, null, 2) + '\n');
|
|
290
|
+
console.log(`🧩 Added "${buildIconsName}" script to consumer package.json`);
|
|
291
|
+
}
|
|
292
|
+
} catch (e) {
|
|
293
|
+
console.warn('⚠️ Could not ensure pds:build-icons script in consumer package.json:', e?.message || e);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// NEW BEHAVIOR: We no longer copy web components automatically to /auto-define/.
|
|
297
|
+
// Reason: static export (pds:export) is now the single source of truth for placing
|
|
298
|
+
// components under [static.root]/components/ (see pds.config.js). This reduces
|
|
299
|
+
// side-effects during npm install and avoids stale/legacy /auto-define/ layout.
|
|
300
|
+
console.log('🚫 Skipping legacy auto-copy of components to ./public/auto-define/.');
|
|
301
|
+
|
|
302
|
+
// Auto-run pds:export by default (can be disabled with PDS_SKIP_EXPORT)
|
|
303
|
+
if (
|
|
304
|
+
process.env.PDS_SKIP_EXPORT === '1' ||
|
|
305
|
+
process.env.PDS_SKIP_EXPORT === 'true' ||
|
|
306
|
+
process.env.npm_config_pds_skip_export === 'true'
|
|
307
|
+
) {
|
|
308
|
+
console.log('⏭️ Skipping pds:export (PDS_SKIP_EXPORT set)');
|
|
309
|
+
console.log('📦 To generate static assets run: npm run pds:export');
|
|
310
|
+
} else {
|
|
311
|
+
console.log('🚀 Running pds:export automatically...');
|
|
312
|
+
const staticModuleUrl = pathToFileURL(path.join(__dirname, 'pds-static.js')).href;
|
|
313
|
+
const previousEnv = {
|
|
314
|
+
PDS_POSTINSTALL: process.env.PDS_POSTINSTALL,
|
|
315
|
+
PDS_LOG_STREAM: process.env.PDS_LOG_STREAM,
|
|
316
|
+
PDS_CONSUMER_ROOT: process.env.PDS_CONSUMER_ROOT,
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
try {
|
|
320
|
+
process.env.PDS_POSTINSTALL = '1';
|
|
321
|
+
process.env.PDS_LOG_STREAM = 'stderr';
|
|
322
|
+
process.env.PDS_CONSUMER_ROOT = consumerRoot;
|
|
323
|
+
|
|
324
|
+
const { runPdsStatic } = await import(staticModuleUrl);
|
|
325
|
+
await runPdsStatic({ cwd: consumerRoot });
|
|
326
|
+
} catch (e) {
|
|
327
|
+
console.error('❌ Auto-export failed:', e?.message || e);
|
|
328
|
+
console.log('💡 You can run it manually: npm run pds:export');
|
|
329
|
+
} finally {
|
|
330
|
+
if (previousEnv.PDS_POSTINSTALL === undefined) {
|
|
331
|
+
delete process.env.PDS_POSTINSTALL;
|
|
332
|
+
} else {
|
|
333
|
+
process.env.PDS_POSTINSTALL = previousEnv.PDS_POSTINSTALL;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (previousEnv.PDS_LOG_STREAM === undefined) {
|
|
337
|
+
delete process.env.PDS_LOG_STREAM;
|
|
338
|
+
} else {
|
|
339
|
+
process.env.PDS_LOG_STREAM = previousEnv.PDS_LOG_STREAM;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (previousEnv.PDS_CONSUMER_ROOT === undefined) {
|
|
343
|
+
delete process.env.PDS_CONSUMER_ROOT;
|
|
344
|
+
} else {
|
|
345
|
+
process.env.PDS_CONSUMER_ROOT = previousEnv.PDS_CONSUMER_ROOT;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
console.log('🎨 (Optional) Build custom icons: npm run pds:build-icons');
|
|
351
|
+
console.log('ℹ️ If you previously relied on /auto-define/, update references to the new static output.');
|
|
352
|
+
|
|
353
|
+
// Tracking file for diagnostics (minimal)
|
|
354
|
+
try {
|
|
355
|
+
const webRoot = await discoverWebRoot(consumerRoot);
|
|
356
|
+
const trackingFile = path.join(webRoot.path, '.pds-install.json');
|
|
357
|
+
const tracking = {
|
|
358
|
+
version: '0.1.0',
|
|
359
|
+
installDate: new Date().toISOString(),
|
|
360
|
+
webRoot: webRoot.relative,
|
|
361
|
+
componentsCopied: 0,
|
|
362
|
+
mode: 'no-copy-postinstall',
|
|
363
|
+
};
|
|
364
|
+
await writeFile(trackingFile, JSON.stringify(tracking, null, 2));
|
|
365
|
+
} catch (e) {
|
|
366
|
+
console.warn('⚠️ Could not write tracking file:', e?.message || e);
|
|
367
|
+
}
|
|
368
|
+
} catch (error) {
|
|
369
|
+
console.error('❌ PDS postinstall failed (non-fatal):', error.message);
|
|
370
|
+
console.log('💡 Static export still available via: npm run pds:export');
|
|
371
|
+
process.exitCode = 1;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Only run when called directly (not when imported)
|
|
376
|
+
if (process.argv[1].endsWith('postinstall.js')) {
|
|
377
|
+
copyPdsAssets().catch(console.error);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export { copyPdsAssets, discoverWebRoot };
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFile, writeFile, mkdir, copyFile, readdir, stat } from 'fs/promises';
|
|
4
|
+
import { createHash } from 'crypto';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
|
|
10
|
+
// Find the PDS package root, whether we're running from the package itself or from node_modules
|
|
11
|
+
async function findPdsRoot() {
|
|
12
|
+
const currentDir = __dirname;
|
|
13
|
+
|
|
14
|
+
// If running from the package itself (development)
|
|
15
|
+
if (currentDir.includes('packages/pds-cli/bin')) {
|
|
16
|
+
return path.resolve(currentDir, '../../../');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// If running from node_modules (consumer app)
|
|
20
|
+
// The structure would be: node_modules/@pure-ds/core/packages/pds-cli/bin
|
|
21
|
+
if (currentDir.includes('node_modules')) {
|
|
22
|
+
let dir = currentDir;
|
|
23
|
+
while (dir !== path.dirname(dir)) {
|
|
24
|
+
// Support both legacy scoped name and new unscoped name
|
|
25
|
+
// node_modules/@pure-ds/core/... OR node_modules/pure-ds/...
|
|
26
|
+
const base = path.basename(dir);
|
|
27
|
+
const parent = path.basename(path.dirname(dir));
|
|
28
|
+
if ((base === 'core' && parent === '@pure-ds') || base === 'pure-ds') {
|
|
29
|
+
return dir;
|
|
30
|
+
}
|
|
31
|
+
dir = path.dirname(dir);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Fallback - navigate up to find package.json with correct name
|
|
36
|
+
let dir = currentDir;
|
|
37
|
+
while (dir !== path.dirname(dir)) {
|
|
38
|
+
try {
|
|
39
|
+
const packagePath = path.join(dir, 'package.json');
|
|
40
|
+
const pkg = JSON.parse(await readFile(packagePath, 'utf8'));
|
|
41
|
+
if (pkg.name === '@pure-ds/core' || pkg.name === 'pure-ds') {
|
|
42
|
+
return dir;
|
|
43
|
+
}
|
|
44
|
+
} catch (e) {
|
|
45
|
+
// Continue searching
|
|
46
|
+
}
|
|
47
|
+
dir = path.dirname(dir);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
throw new Error('Could not find PDS package root');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Sync PDS assets to consuming app's public directory
|
|
55
|
+
* Copies:
|
|
56
|
+
* - public/pds/components/* (or legacy public/auto-define/*) -> <targetDir>/components/*
|
|
57
|
+
* - (icons no longer synced; static export focuses on components and styles)
|
|
58
|
+
*
|
|
59
|
+
* Usage: node node_modules/pure-ds/packages/pds-cli/bin/sync-assets.js [options]
|
|
60
|
+
* Options:
|
|
61
|
+
* --target=<path> Target directory (default: ./public)
|
|
62
|
+
* --force Overwrite user-modified files
|
|
63
|
+
* --dry-run Show what would be synced without copying
|
|
64
|
+
* --verbose, -v Show detailed sync information
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
async function syncAssets(options = {}) {
|
|
68
|
+
const {
|
|
69
|
+
targetDir = './public',
|
|
70
|
+
force = false,
|
|
71
|
+
dryRun = false,
|
|
72
|
+
verbose = false
|
|
73
|
+
} = options;
|
|
74
|
+
|
|
75
|
+
console.log('🔄 Syncing PDS assets...');
|
|
76
|
+
|
|
77
|
+
// Find PDS package root
|
|
78
|
+
const pdsRoot = await findPdsRoot();
|
|
79
|
+
|
|
80
|
+
// Prefer new packaged location; fall back to legacy paths
|
|
81
|
+
let autoDefineSource = path.join(pdsRoot, 'public/assets/pds/components');
|
|
82
|
+
try {
|
|
83
|
+
await stat(autoDefineSource);
|
|
84
|
+
} catch {
|
|
85
|
+
try {
|
|
86
|
+
autoDefineSource = path.join(pdsRoot, 'public/pds/components');
|
|
87
|
+
await stat(autoDefineSource);
|
|
88
|
+
} catch {
|
|
89
|
+
autoDefineSource = path.join(pdsRoot, 'public/auto-define');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Target directories
|
|
94
|
+
const autoDefineTarget = path.join(process.cwd(), targetDir, 'components');
|
|
95
|
+
|
|
96
|
+
// Load or create asset tracking file
|
|
97
|
+
const trackingFile = path.join(process.cwd(), '.pds-assets.json');
|
|
98
|
+
let tracking = {};
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
const trackingData = await readFile(trackingFile, 'utf-8');
|
|
102
|
+
tracking = JSON.parse(trackingData);
|
|
103
|
+
} catch (e) {
|
|
104
|
+
// First run or corrupted file
|
|
105
|
+
tracking = {
|
|
106
|
+
version: '0.1.0',
|
|
107
|
+
lastSync: null,
|
|
108
|
+
checksums: {},
|
|
109
|
+
userModified: {}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const newChecksums = {};
|
|
114
|
+
const conflicts = [];
|
|
115
|
+
const synced = [];
|
|
116
|
+
|
|
117
|
+
// Helper to calculate file hash
|
|
118
|
+
const getFileHash = async (filePath) => {
|
|
119
|
+
try {
|
|
120
|
+
const content = await readFile(filePath);
|
|
121
|
+
return createHash('sha256').update(content).digest('hex');
|
|
122
|
+
} catch (e) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// Helper to sync a single file
|
|
128
|
+
const syncFile = async (sourcePath, targetPath, relativeKey) => {
|
|
129
|
+
try {
|
|
130
|
+
// Ensure target directory exists
|
|
131
|
+
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
132
|
+
|
|
133
|
+
const sourceHash = await getFileHash(sourcePath);
|
|
134
|
+
const targetHash = await getFileHash(targetPath);
|
|
135
|
+
const knownHash = tracking.checksums[relativeKey];
|
|
136
|
+
|
|
137
|
+
newChecksums[relativeKey] = sourceHash;
|
|
138
|
+
|
|
139
|
+
// Conflict detection
|
|
140
|
+
if (targetHash && targetHash !== sourceHash && targetHash !== knownHash) {
|
|
141
|
+
conflicts.push({
|
|
142
|
+
file: relativeKey,
|
|
143
|
+
path: targetPath,
|
|
144
|
+
reason: 'User modified file conflicts with PDS update'
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
if (!force) {
|
|
148
|
+
if (verbose) {
|
|
149
|
+
console.log(`⚠️ Skipping ${relativeKey} (user modified)`);
|
|
150
|
+
}
|
|
151
|
+
tracking.userModified[relativeKey] = targetHash;
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Copy file if needed
|
|
157
|
+
if (!targetHash || targetHash !== sourceHash || force) {
|
|
158
|
+
if (!dryRun) {
|
|
159
|
+
await copyFile(sourcePath, targetPath);
|
|
160
|
+
}
|
|
161
|
+
synced.push(relativeKey);
|
|
162
|
+
|
|
163
|
+
if (verbose) {
|
|
164
|
+
console.log(`📁 ${dryRun ? '[DRY RUN] ' : ''}Synced ${relativeKey}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
} catch (e) {
|
|
168
|
+
console.warn(`⚠️ Could not sync ${relativeKey}:`, e.message);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// Helper to sync a directory
|
|
173
|
+
const syncDirectory = async (sourceDir, targetDir, prefix = '') => {
|
|
174
|
+
try {
|
|
175
|
+
await mkdir(targetDir, { recursive: true });
|
|
176
|
+
const files = await readdir(sourceDir);
|
|
177
|
+
|
|
178
|
+
for (const file of files) {
|
|
179
|
+
const sourcePath = path.join(sourceDir, file);
|
|
180
|
+
const targetPath = path.join(targetDir, file);
|
|
181
|
+
const relativeKey = `${prefix}${file}`;
|
|
182
|
+
|
|
183
|
+
const sourceStat = await stat(sourcePath);
|
|
184
|
+
if (sourceStat.isDirectory()) {
|
|
185
|
+
await syncDirectory(sourcePath, targetPath, `${relativeKey}/`);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
await syncFile(sourcePath, targetPath, relativeKey);
|
|
190
|
+
}
|
|
191
|
+
} catch (e) {
|
|
192
|
+
console.warn(`⚠️ Could not sync ${sourceDir}:`, e.message);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// Sync components directory
|
|
197
|
+
if (verbose) {
|
|
198
|
+
console.log('📁 Syncing components...');
|
|
199
|
+
}
|
|
200
|
+
await syncDirectory(autoDefineSource, autoDefineTarget, 'components/');
|
|
201
|
+
|
|
202
|
+
// Note: icons are not synced in this flow; use pds:export if needed
|
|
203
|
+
|
|
204
|
+
// Update tracking file
|
|
205
|
+
if (!dryRun) {
|
|
206
|
+
tracking.checksums = { ...tracking.checksums, ...newChecksums };
|
|
207
|
+
tracking.lastSync = new Date().toISOString();
|
|
208
|
+
await writeFile(trackingFile, JSON.stringify(tracking, null, 2));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Report results
|
|
212
|
+
console.log(`✅ Sync complete: ${synced.length} files updated`);
|
|
213
|
+
|
|
214
|
+
if (conflicts.length > 0) {
|
|
215
|
+
console.log(`⚠️ ${conflicts.length} conflicts detected:`);
|
|
216
|
+
conflicts.forEach(c => {
|
|
217
|
+
console.log(` - ${c.file}: ${c.reason}`);
|
|
218
|
+
});
|
|
219
|
+
console.log(' Use --force to overwrite user modifications');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (verbose) {
|
|
223
|
+
console.log(`📊 Tracking file: ${trackingFile}`);
|
|
224
|
+
console.log(`📁 Components: ${autoDefineTarget}`);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
synced: synced.length,
|
|
229
|
+
conflicts: conflicts.length,
|
|
230
|
+
tracking
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// CLI interface
|
|
235
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
236
|
+
const args = process.argv.slice(2);
|
|
237
|
+
const options = {
|
|
238
|
+
force: args.includes('--force'),
|
|
239
|
+
dryRun: args.includes('--dry-run'),
|
|
240
|
+
verbose: args.includes('--verbose') || args.includes('-v'),
|
|
241
|
+
targetDir: args.find(arg => arg.startsWith('--target='))?.split('=')[1] || './public'
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
try {
|
|
245
|
+
await syncAssets(options);
|
|
246
|
+
} catch (error) {
|
|
247
|
+
console.error('❌ Sync failed:', error.message);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export { syncAssets };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { resolvePublicAssetURL, getPublicRootCandidate, __internal } from '../../../src/js/pds-core/pds-paths.js';
|
|
3
|
+
|
|
4
|
+
const URL_PATTERN = __internal.URL_PATTERN;
|
|
5
|
+
const PDS_SEGMENT = __internal.DEFAULT_SEGMENT;
|
|
6
|
+
|
|
7
|
+
function trimTrailingSeparators(value) {
|
|
8
|
+
return value.replace(/[\\/]+$/, '');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function ensurePdsPath(input) {
|
|
12
|
+
if (!input || typeof input !== 'string') return input;
|
|
13
|
+
let target = trimTrailingSeparators(input);
|
|
14
|
+
if (/[\\/]pds$/i.test(target)) {
|
|
15
|
+
return target;
|
|
16
|
+
}
|
|
17
|
+
return path.join(target, PDS_SEGMENT);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function resolvePublicAssetDirectory(config, options = {}) {
|
|
21
|
+
const webRootPath = options.webRootPath;
|
|
22
|
+
const cwd = options.cwd || process.cwd();
|
|
23
|
+
const overrideRoot = options.overrideRoot;
|
|
24
|
+
const candidate = (overrideRoot ?? getPublicRootCandidate(config)) || '';
|
|
25
|
+
|
|
26
|
+
if (candidate && typeof candidate === 'string' && !URL_PATTERN.test(candidate.trim())) {
|
|
27
|
+
let target = candidate.trim();
|
|
28
|
+
if (target) {
|
|
29
|
+
if (!path.isAbsolute(target)) {
|
|
30
|
+
target = path.resolve(cwd, target);
|
|
31
|
+
}
|
|
32
|
+
return ensurePdsPath(target);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (webRootPath) {
|
|
37
|
+
return ensurePdsPath(path.join(webRootPath, 'assets'));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return ensurePdsPath(path.resolve(cwd, 'public', 'assets'));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function isUrlLike(value) {
|
|
44
|
+
return typeof value === 'string' && URL_PATTERN.test(value.trim());
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { resolvePublicAssetURL, getPublicRootCandidate };
|