@pure-ds/core 0.4.37 → 0.5.2

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 (146) hide show
  1. package/dist/types/pds.d.ts +34 -11
  2. package/dist/types/public/assets/auto-definer-XWHRBQPU.d.ts +9 -0
  3. package/dist/types/public/assets/auto-definer-XWHRBQPU.d.ts.map +1 -0
  4. package/dist/types/public/assets/chunk-746HIXIK.d.ts +52 -0
  5. package/dist/types/public/assets/chunk-746HIXIK.d.ts.map +1 -0
  6. package/dist/types/public/assets/chunk-APJV5T3J.d.ts +106 -0
  7. package/dist/types/public/assets/chunk-APJV5T3J.d.ts.map +1 -0
  8. package/dist/types/public/assets/chunk-BEPKFFM7.d.ts +398 -0
  9. package/dist/types/public/assets/chunk-BEPKFFM7.d.ts.map +1 -0
  10. package/dist/types/public/assets/chunk-ISS7UH5H.d.ts +2424 -0
  11. package/dist/types/public/assets/chunk-ISS7UH5H.d.ts.map +1 -0
  12. package/dist/types/public/assets/chunk-RUPLQUDG.d.ts +582 -0
  13. package/dist/types/public/assets/chunk-RUPLQUDG.d.ts.map +1 -0
  14. package/dist/types/public/assets/chunk-USML4NYF.d.ts +18 -0
  15. package/dist/types/public/assets/chunk-USML4NYF.d.ts.map +1 -0
  16. package/dist/types/public/assets/chunk-Z47A3HLT.d.ts +3 -0
  17. package/dist/types/public/assets/chunk-Z47A3HLT.d.ts.map +1 -0
  18. package/dist/types/public/assets/js/auto-definer-HZLD2XF4.d.ts +9 -0
  19. package/dist/types/public/assets/js/auto-definer-HZLD2XF4.d.ts.map +1 -0
  20. package/dist/types/public/assets/js/chunk-6A6DFAIG.d.ts +88 -0
  21. package/dist/types/public/assets/js/chunk-6A6DFAIG.d.ts.map +1 -0
  22. package/dist/types/public/assets/js/chunk-746HIXIK.d.ts +52 -0
  23. package/dist/types/public/assets/js/chunk-746HIXIK.d.ts.map +1 -0
  24. package/dist/types/public/assets/js/chunk-A3TZGIYX.d.ts +4 -0
  25. package/dist/types/public/assets/js/chunk-A3TZGIYX.d.ts.map +1 -0
  26. package/dist/types/public/assets/js/chunk-BEPKFFM7.d.ts +398 -0
  27. package/dist/types/public/assets/js/chunk-BEPKFFM7.d.ts.map +1 -0
  28. package/dist/types/public/assets/js/chunk-OTTRJ5MB.d.ts +1695 -0
  29. package/dist/types/public/assets/js/chunk-OTTRJ5MB.d.ts.map +1 -0
  30. package/dist/types/public/assets/js/chunk-RBPKHG76.d.ts +747 -0
  31. package/dist/types/public/assets/js/chunk-RBPKHG76.d.ts.map +1 -0
  32. package/dist/types/public/assets/js/chunk-RUPLQUDG.d.ts +582 -0
  33. package/dist/types/public/assets/js/chunk-RUPLQUDG.d.ts.map +1 -0
  34. package/dist/types/public/assets/js/chunk-SMD2R3CX.d.ts +68 -0
  35. package/dist/types/public/assets/js/chunk-SMD2R3CX.d.ts.map +1 -0
  36. package/dist/types/public/assets/js/chunk-Y73DA2D5.d.ts +15 -0
  37. package/dist/types/public/assets/js/chunk-Y73DA2D5.d.ts.map +1 -0
  38. package/dist/types/public/assets/js/chunks/auto-definer-X7MSXKTU.d.ts +9 -0
  39. package/dist/types/public/assets/js/chunks/auto-definer-X7MSXKTU.d.ts.map +1 -0
  40. package/dist/types/public/assets/js/chunks/chunk-7BDQH5CT.d.ts +485 -0
  41. package/dist/types/public/assets/js/chunks/chunk-7BDQH5CT.d.ts.map +1 -0
  42. package/dist/types/public/assets/js/chunks/chunk-MWB3S7NG.d.ts +3 -0
  43. package/dist/types/public/assets/js/chunks/chunk-MWB3S7NG.d.ts.map +1 -0
  44. package/dist/types/public/assets/js/chunks/chunk-WIMLORAU.d.ts +5 -0
  45. package/dist/types/public/assets/js/chunks/chunk-WIMLORAU.d.ts.map +1 -0
  46. package/dist/types/public/assets/js/chunks/chunk-WN4Y2ELN.d.ts +833 -0
  47. package/dist/types/public/assets/js/chunks/chunk-WN4Y2ELN.d.ts.map +1 -0
  48. package/dist/types/public/assets/js/chunks/chunk-XQOUIBLO.d.ts +1687 -0
  49. package/dist/types/public/assets/js/chunks/chunk-XQOUIBLO.d.ts.map +1 -0
  50. package/dist/types/public/assets/js/chunks/font-loader-VN5SRNOD.d.ts +5 -0
  51. package/dist/types/public/assets/js/chunks/font-loader-VN5SRNOD.d.ts.map +1 -0
  52. package/dist/types/public/assets/js/chunks/pds-live-validation-BQPWN5JG.d.ts +38 -0
  53. package/dist/types/public/assets/js/chunks/pds-live-validation-BQPWN5JG.d.ts.map +1 -0
  54. package/dist/types/public/assets/js/common-WIAC4WAJ.d.ts +4 -0
  55. package/dist/types/public/assets/js/common-WIAC4WAJ.d.ts.map +1 -0
  56. package/dist/types/public/assets/js/pds-config-WEBAXXSM.d.ts +4 -0
  57. package/dist/types/public/assets/js/pds-config-WEBAXXSM.d.ts.map +1 -0
  58. package/dist/types/public/assets/js/pds-core/pds-generator.d.ts +700 -0
  59. package/dist/types/public/assets/js/pds-core/pds-generator.d.ts.map +1 -0
  60. package/dist/types/public/assets/js/pds-core/pds-utilities.d.ts +27 -0
  61. package/dist/types/public/assets/js/pds-core/pds-utilities.d.ts.map +1 -0
  62. package/dist/types/public/assets/js/pds-enums-DCBZHS64.d.ts +3 -0
  63. package/dist/types/public/assets/js/pds-enums-DCBZHS64.d.ts.map +1 -0
  64. package/dist/types/public/assets/js/pds-gen.d.ts +106 -0
  65. package/dist/types/public/assets/js/pds-gen.d.ts.map +1 -0
  66. package/dist/types/public/assets/js/pds-live.d.ts +11 -0
  67. package/dist/types/public/assets/js/pds-live.d.ts.map +1 -0
  68. package/dist/types/public/assets/js/pds-manager.d.ts +1047 -0
  69. package/dist/types/public/assets/js/pds-manager.d.ts.map +1 -0
  70. package/dist/types/public/assets/js/pds-ontology-2DICJXHO.d.ts +9 -0
  71. package/dist/types/public/assets/js/pds-ontology-2DICJXHO.d.ts.map +1 -0
  72. package/dist/types/public/assets/js/pds-query-B54LBKKR.d.ts +70 -0
  73. package/dist/types/public/assets/js/pds-query-B54LBKKR.d.ts.map +1 -0
  74. package/dist/types/public/assets/js/pds.d.ts +1 -18
  75. package/dist/types/public/assets/js/pds.d.ts.map +1 -1
  76. package/dist/types/public/assets/pds-ontology-ZO6TJHO3.d.ts +9 -0
  77. package/dist/types/public/assets/pds-ontology-ZO6TJHO3.d.ts.map +1 -0
  78. package/dist/types/src/js/common/pds-core/pds-config.d.ts +757 -0
  79. package/dist/types/src/js/common/pds-core/pds-config.d.ts.map +1 -0
  80. package/dist/types/src/js/common/pds-core/pds-enhancers.d.ts +28 -0
  81. package/dist/types/src/js/common/pds-core/pds-enhancers.d.ts.map +1 -0
  82. package/dist/types/src/js/common/pds-core/pds-enums.d.ts +87 -0
  83. package/dist/types/src/js/common/pds-core/pds-enums.d.ts.map +1 -0
  84. package/dist/types/src/js/common/pds-core/pds-generator.d.ts +700 -0
  85. package/dist/types/src/js/common/pds-core/pds-generator.d.ts.map +1 -0
  86. package/dist/types/src/js/common/pds-core/pds-ontology.d.ts +380 -0
  87. package/dist/types/src/js/common/pds-core/pds-ontology.d.ts.map +1 -0
  88. package/dist/types/src/js/common/pds-core/pds-paths.d.ts +37 -0
  89. package/dist/types/src/js/common/pds-core/pds-paths.d.ts.map +1 -0
  90. package/dist/types/src/js/common/pds-core/pds-query.d.ts +102 -0
  91. package/dist/types/src/js/common/pds-core/pds-query.d.ts.map +1 -0
  92. package/dist/types/src/js/common/pds-core/pds-registry.d.ts +35 -0
  93. package/dist/types/src/js/common/pds-core/pds-registry.d.ts.map +1 -0
  94. package/dist/types/src/js/common/pds-core/pds-utilities.d.ts +27 -0
  95. package/dist/types/src/js/common/pds-core/pds-utilities.d.ts.map +1 -0
  96. package/dist/types/src/js/pds-core/pds-generator.d.ts +38 -46
  97. package/dist/types/src/js/pds-core/pds-generator.d.ts.map +1 -1
  98. package/dist/types/src/js/pds-core/pds-live.d.ts +39 -0
  99. package/dist/types/src/js/pds-core/pds-live.d.ts.map +1 -0
  100. package/dist/types/src/js/pds-core/pds-runtime.d.ts +39 -0
  101. package/dist/types/src/js/pds-core/pds-runtime.d.ts.map +1 -0
  102. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts +60 -0
  103. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts.map +1 -0
  104. package/dist/types/src/js/pds-core/pds-utilities.d.ts +27 -0
  105. package/dist/types/src/js/pds-core/pds-utilities.d.ts.map +1 -0
  106. package/dist/types/src/js/pds-gen.d.ts +48 -0
  107. package/dist/types/src/js/pds-gen.d.ts.map +1 -0
  108. package/dist/types/src/js/pds-live-runtime.d.ts +7 -0
  109. package/dist/types/src/js/pds-live-runtime.d.ts.map +1 -0
  110. package/dist/types/src/js/pds-live-validation.d.ts +44 -0
  111. package/dist/types/src/js/pds-live-validation.d.ts.map +1 -0
  112. package/dist/types/src/js/pds-live.d.ts +11 -0
  113. package/dist/types/src/js/pds-live.d.ts.map +1 -0
  114. package/dist/types/src/js/pds-manager.d.ts +2 -0
  115. package/dist/types/src/js/pds-manager.d.ts.map +1 -0
  116. package/dist/types/src/js/pds.d.ts +6 -33
  117. package/dist/types/src/js/pds.d.ts.map +1 -1
  118. package/package.json +11 -12
  119. package/packages/pds-cli/bin/{generate-css-data.mjs → generate-css-data.js} +563 -563
  120. package/packages/pds-cli/bin/{generate-manifest.mjs → generate-manifest.js} +352 -352
  121. package/packages/pds-cli/bin/{pds-build-icons.mjs → pds-build-icons.js} +152 -152
  122. package/packages/pds-cli/bin/{pds-dx.mjs → pds-dx.js} +114 -114
  123. package/packages/pds-cli/bin/{pds-init-config.mjs → pds-init-config.js} +34 -34
  124. package/packages/pds-cli/bin/{pds-setup-copilot.mjs → pds-setup-copilot.js} +106 -106
  125. package/packages/pds-cli/bin/{pds-static.mjs → pds-static.js} +597 -581
  126. package/packages/pds-cli/bin/{pds.mjs → pds.js} +127 -127
  127. package/packages/pds-cli/bin/postinstall.mjs +522 -563
  128. package/packages/pds-cli/bin/{sync-assets.mjs → sync-assets.js} +251 -251
  129. package/packages/pds-cli/lib/{asset-roots.mjs → asset-roots.js} +47 -47
  130. package/packages/pds-cli/lib/{fs-writer.mjs → fs-writer.js} +75 -75
  131. package/public/assets/js/app.js +95 -118
  132. package/public/assets/js/pds-manager.js +3251 -0
  133. package/public/assets/js/pds.js +10 -3201
  134. package/readme.md +2014 -2016
  135. package/src/js/pds-core/pds-enhancers.js +518 -518
  136. package/src/js/pds-core/pds-enums.js +86 -86
  137. package/src/js/pds-core/pds-generator.js +255 -185
  138. package/src/js/pds-core/pds-live.js +434 -0
  139. package/src/js/pds-core/pds-paths.js +109 -109
  140. package/src/js/pds-core/pds-registry.js +79 -79
  141. package/src/js/pds-core/pds-runtime.js +184 -0
  142. package/src/js/pds-core/pds-start-helpers.js +405 -0
  143. package/src/js/pds.d.ts +34 -11
  144. package/src/js/pds.js +43 -1182
  145. package/getting-started.md +0 -626
  146. package/src/js/pds-core/pds.d.ts +0 -129
@@ -1,352 +1,352 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Generate Custom Elements Manifest
5
- * Creates custom-elements.json with metadata for all PDS components
6
- */
7
-
8
- import { writeFile, mkdir, readFile } from 'fs/promises';
9
- import { existsSync } from 'fs';
10
- import path from 'path';
11
- import { fileURLToPath, pathToFileURL } from 'url';
12
- import { execSync } from 'child_process';
13
-
14
- const __filename = fileURLToPath(import.meta.url);
15
- const __dirname = path.dirname(__filename);
16
- const repoRoot = path.resolve(__dirname, '../../../');
17
-
18
- // Colors for terminal output
19
- const COLORS = {
20
- reset: '\x1b[0m',
21
- bold: '\x1b[1m',
22
- green: '\x1b[32m',
23
- yellow: '\x1b[33m',
24
- blue: '\x1b[34m',
25
- red: '\x1b[31m',
26
- };
27
-
28
- const shouldLogToStderr = () => process.env.PDS_LOG_STREAM === 'stderr' || process.env.PDS_POSTINSTALL === '1';
29
- const log = (msg, color = 'reset') => {
30
- const colorCode = COLORS[color] || '';
31
- const text = `${colorCode}${msg}${COLORS.reset}`;
32
- if (shouldLogToStderr()) {
33
- process.stderr.write(`${text}\n`);
34
- } else {
35
- console.log(text);
36
- }
37
- };
38
-
39
- async function copyBundledManifest(targetDir) {
40
- try {
41
- const sourceManifest = path.join(repoRoot, 'custom-elements.json');
42
- if (!existsSync(sourceManifest)) {
43
- log('⚠️ Packaged custom-elements.json not found; skipping manifest copy.', 'yellow');
44
- return false;
45
- }
46
-
47
- if (targetDir) {
48
- await mkdir(targetDir, { recursive: true });
49
- const manifestContent = await readFile(sourceManifest, 'utf-8');
50
- const manifestTarget = path.join(targetDir, 'custom-elements.json');
51
- await writeFile(manifestTarget, manifestContent, 'utf-8');
52
- log(`✅ Manifest copied to ${path.relative(process.cwd(), manifestTarget)}`, 'green');
53
- } else {
54
- log('✅ Packaged custom-elements.json is available', 'green');
55
- }
56
-
57
- const packagedVscodeData = path.join(repoRoot, 'public/assets/pds/vscode-custom-data.json');
58
- if (targetDir && existsSync(packagedVscodeData)) {
59
- const vscodeContent = await readFile(packagedVscodeData, 'utf-8');
60
- const vscodeTarget = path.join(targetDir, 'vscode-custom-data.json');
61
- await writeFile(vscodeTarget, vscodeContent, 'utf-8');
62
- log(`✅ VS Code custom data copied to ${path.relative(process.cwd(), vscodeTarget)}`, 'green');
63
- }
64
-
65
- return true;
66
- } catch (error) {
67
- log(`❌ Failed to copy packaged manifest: ${error?.message || error}`, 'red');
68
- return false;
69
- }
70
- }
71
-
72
- /**
73
- * Convert Custom Elements Manifest to VS Code Custom Data format
74
- */
75
- async function convertToVSCodeFormat(manifest) {
76
- const tags = [];
77
-
78
- // Load icon configuration
79
- let availableIcons = [];
80
- try {
81
- const configPath = path.join(repoRoot, 'src/js/pds-core/pds-config.js');
82
- const { presets } = await import(pathToFileURL(configPath).href);
83
-
84
- // Get icons from default preset
85
- const iconConfig = presets?.default?.icons?.include || {};
86
-
87
- // Extract all icon names from all categories
88
- availableIcons = Array.from(new Set(
89
- Object.values(iconConfig).flat()
90
- )).filter(Boolean).sort();
91
-
92
- if (availableIcons.length > 0) {
93
- log(`🎨 Found ${availableIcons.length} icons in configuration`, 'blue');
94
- }
95
- } catch (error) {
96
- log(`⚠️ Could not load icon configuration: ${error.message}`, 'yellow');
97
- }
98
-
99
- // Load enhancers for data attribute autocomplete
100
- let enhancerAttributes = [];
101
- try {
102
- const pdsPath = path.join(repoRoot, 'src/js/pds.js');
103
- const pdsModule = await import(pathToFileURL(pdsPath).href);
104
- const enhancers = pdsModule?.PDS?.defaultEnhancers || [];
105
-
106
- for (const enhancer of enhancers) {
107
- // Extract data-* attributes from selectors
108
- const selectorMatch = enhancer.selector.match(/\[data-([^\]]+)\]/);
109
- if (selectorMatch) {
110
- const attrName = `data-${selectorMatch[1]}`;
111
- let demoCode = '';
112
-
113
- // Get demo HTML if available
114
- if (enhancer.demoHtml) {
115
- try {
116
- demoCode = typeof enhancer.demoHtml === 'function'
117
- ? enhancer.demoHtml()
118
- : enhancer.demoHtml;
119
- // Clean up the demo code
120
- demoCode = demoCode.trim().replace(/\n\s+/g, '\n').replace(/\n{3,}/g, '\n\n');
121
- } catch (e) {
122
- demoCode = '';
123
- }
124
- }
125
-
126
- enhancerAttributes.push({
127
- name: attrName,
128
- description: enhancer.description || `Progressive enhancement: ${enhancer.selector}`,
129
- demoCode: demoCode,
130
- selector: enhancer.selector
131
- });
132
- }
133
- }
134
-
135
- if (enhancerAttributes.length > 0) {
136
- log(`🔧 Found ${enhancerAttributes.length} enhancement attributes`, 'blue');
137
- }
138
- } catch (error) {
139
- log(`⚠️ Could not load enhancers: ${error.message}`, 'yellow');
140
- }
141
-
142
- manifest.modules?.forEach(module => {
143
- module.declarations?.forEach(declaration => {
144
- if (declaration.tagName && declaration.customElement) {
145
- const tag = {
146
- name: declaration.tagName,
147
- description: declaration.description || `${declaration.name} component`
148
- };
149
-
150
- // Add attributes
151
- if (declaration.attributes && declaration.attributes.length > 0) {
152
- tag.attributes = declaration.attributes.map(attr => {
153
- const attribute = {
154
- name: attr.name,
155
- description: attr.description || ''
156
- };
157
-
158
- // Special handling for pds-icon's icon attribute - add available icon names
159
- if (declaration.tagName === 'pds-icon' && attr.name === 'icon' && availableIcons.length > 0) {
160
- attribute.values = availableIcons.map(iconName => ({
161
- name: iconName,
162
- description: `${iconName} icon`
163
- }));
164
- }
165
- // Check if type indicates enum values
166
- else if (attr.type?.text) {
167
- const typeText = attr.type.text;
168
- // Match patterns like "bottom" | "top" | "left" | "right"
169
- const enumMatch = typeText.match(/"([^"]+)"/g);
170
- if (enumMatch && enumMatch.length > 1) {
171
- attribute.values = enumMatch.map(val => ({ name: val.replace(/"/g, '') }));
172
- }
173
- }
174
-
175
- // Add boolean value set for boolean types
176
- if (attr.type?.text === 'boolean') {
177
- attribute.valueSet = 'v';
178
- }
179
-
180
- return attribute;
181
- });
182
- }
183
-
184
- tags.push(tag);
185
- }
186
- });
187
- });
188
-
189
- // Build global attributes for data-* enhancements
190
- const globalAttributes = enhancerAttributes.map(attr => {
191
- const description = attr.demoCode
192
- ? `${attr.description}\n\nExample:\n${attr.demoCode}`
193
- : attr.description;
194
-
195
- return {
196
- name: attr.name,
197
- description: description,
198
- valueSet: 'v' // Boolean-like attributes
199
- };
200
- });
201
-
202
- return {
203
- version: 1.1,
204
- tags,
205
- globalAttributes: globalAttributes.length > 0 ? globalAttributes : undefined
206
- };
207
- }
208
-
209
- /**
210
- * Create pds.html-data.json in project root
211
- */
212
- async function createHtmlDataConfig(vscodeDataPath) {
213
- const config = {
214
- "html.customData": [vscodeDataPath]
215
- };
216
-
217
- const configPath = path.join(repoRoot, 'pds.html-data.json');
218
- await writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
219
- log(`✅ Created pds.html-data.json`, 'green');
220
- return configPath;
221
- }
222
-
223
- /**
224
- * Reload VS Code window
225
- */
226
- function reloadVSCode() {
227
- // Note: Automatic reload would require VS Code extension API
228
- // For now, just inform the user to reload manually
229
- log('⚠️ Please reload VS Code to activate the updated custom data:', 'yellow');
230
- log(' Press Ctrl+Shift+P → "Developer: Reload Window"', 'blue');
231
- }
232
-
233
- /**
234
- * Analyze components and generate manifest
235
- */
236
- async function generateManifest(targetDir) {
237
- try {
238
- log('📋 Generating Custom Elements Manifest...', 'bold');
239
-
240
- const analyzerInstalled = existsSync(path.join(repoRoot, 'node_modules/@custom-elements-manifest/analyzer'));
241
- const runningFromPostinstall = process.env.PDS_POSTINSTALL === '1';
242
-
243
- if (!analyzerInstalled || runningFromPostinstall) {
244
- if (!analyzerInstalled) {
245
- const color = runningFromPostinstall ? 'blue' : 'yellow';
246
- log('ℹ️ Using packaged Custom Elements manifest (analyzer not available).', color);
247
- if (!runningFromPostinstall) {
248
- log(' Install @custom-elements-manifest/analyzer to enable manifest regeneration.', 'yellow');
249
- }
250
- } else {
251
- log('ℹ️ Skipping analyzer during postinstall; using packaged manifest.', 'blue');
252
- }
253
- return copyBundledManifest(targetDir);
254
- }
255
-
256
- // Run the analyzer
257
- const configPath = path.join(repoRoot, 'custom-elements-manifest.config.js');
258
-
259
- log('🔍 Analyzing components...', 'blue');
260
-
261
- try {
262
- execSync(`npx cem analyze --config ${configPath}`, {
263
- cwd: repoRoot,
264
- stdio: 'inherit'
265
- });
266
-
267
- // Post-process: Remove private members from the generated manifest
268
- const sourceManifest = path.join(repoRoot, 'custom-elements.json');
269
- if (existsSync(sourceManifest)) {
270
- log('🧹 Cleaning private members from manifest...', 'blue');
271
- const manifestContent = await readFile(sourceManifest, 'utf-8');
272
- const manifest = JSON.parse(manifestContent);
273
-
274
- // Filter out private members from all declarations
275
- manifest.modules?.forEach(module => {
276
- module.declarations?.forEach(declaration => {
277
- if (declaration.members) {
278
- declaration.members = declaration.members.filter(member => {
279
- // Keep only public members (exclude private and those starting with #)
280
- return member.privacy !== 'private' && !member.name?.startsWith('#');
281
- });
282
- }
283
- });
284
- });
285
-
286
- // Write cleaned manifest back
287
- await writeFile(sourceManifest, JSON.stringify(manifest, null, 2), 'utf-8');
288
- log('✅ Private members removed', 'green');
289
- }
290
-
291
- // Copy manifest to target directory if specified
292
- if (targetDir) {
293
- const targetManifest = path.join(targetDir, 'custom-elements.json');
294
-
295
- if (existsSync(sourceManifest)) {
296
- await mkdir(path.dirname(targetManifest), { recursive: true });
297
- const manifestContent = await readFile(sourceManifest, 'utf-8');
298
- await writeFile(targetManifest, manifestContent, 'utf-8');
299
- log(`✅ Manifest copied to ${path.relative(process.cwd(), targetManifest)}`, 'green');
300
- }
301
- }
302
-
303
- log('✅ Custom Elements Manifest generated', 'green');
304
-
305
- // Step 1: Generate VS Code custom data file
306
- log('🔧 Generating VS Code custom data...', 'blue');
307
- const manifestContent = await readFile(sourceManifest, 'utf-8');
308
- const manifest = JSON.parse(manifestContent);
309
- const vscodeData = await convertToVSCodeFormat(manifest);
310
-
311
- // Write to both locations
312
- const vscodeDataPath = path.join(repoRoot, 'public/assets/pds/vscode-custom-data.json');
313
- await mkdir(path.dirname(vscodeDataPath), { recursive: true });
314
- await writeFile(vscodeDataPath, JSON.stringify(vscodeData, null, 2), 'utf-8');
315
- log(`✅ VS Code custom data generated at ${path.relative(repoRoot, vscodeDataPath)}`, 'green');
316
-
317
- // Also copy to target directory if specified
318
- if (targetDir) {
319
- const targetVSCodeData = path.join(targetDir, 'vscode-custom-data.json');
320
- await writeFile(targetVSCodeData, JSON.stringify(vscodeData, null, 2), 'utf-8');
321
- log(`✅ VS Code custom data copied to ${path.relative(process.cwd(), targetVSCodeData)}`, 'green');
322
- }
323
-
324
- // Step 2: Create pds.html-data.json in project root
325
- const relativePath = 'public/assets/pds/vscode-custom-data.json';
326
- await createHtmlDataConfig(relativePath);
327
-
328
- // Step 3: Reload VS Code window
329
- log('🔄 Reloading VS Code...', 'blue');
330
- reloadVSCode();
331
-
332
- return true;
333
- } catch (error) {
334
- log(`❌ Manifest generation failed: ${error.message}`, 'red');
335
- return false;
336
- }
337
-
338
- } catch (error) {
339
- log(`❌ Error: ${error.message}`, 'red');
340
- return false;
341
- }
342
- }
343
-
344
- export { generateManifest };
345
-
346
- // Run if called directly
347
- if (process.argv[1] && (process.argv[1].endsWith('generate-manifest.mjs') || process.argv[1].endsWith('generate-manifest.js'))) {
348
- const targetDir = process.argv[2] || null;
349
- generateManifest(targetDir).then(success => {
350
- process.exit(success ? 0 : 1);
351
- });
352
- }
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Generate Custom Elements Manifest
5
+ * Creates custom-elements.json with metadata for all PDS components
6
+ */
7
+
8
+ import { writeFile, mkdir, readFile } from 'fs/promises';
9
+ import { existsSync } from 'fs';
10
+ import path from 'path';
11
+ import { fileURLToPath, pathToFileURL } from 'url';
12
+ import { execSync } from 'child_process';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+ const repoRoot = path.resolve(__dirname, '../../../');
17
+
18
+ // Colors for terminal output
19
+ const COLORS = {
20
+ reset: '\x1b[0m',
21
+ bold: '\x1b[1m',
22
+ green: '\x1b[32m',
23
+ yellow: '\x1b[33m',
24
+ blue: '\x1b[34m',
25
+ red: '\x1b[31m',
26
+ };
27
+
28
+ const shouldLogToStderr = () => process.env.PDS_LOG_STREAM === 'stderr' || process.env.PDS_POSTINSTALL === '1';
29
+ const log = (msg, color = 'reset') => {
30
+ const colorCode = COLORS[color] || '';
31
+ const text = `${colorCode}${msg}${COLORS.reset}`;
32
+ if (shouldLogToStderr()) {
33
+ process.stderr.write(`${text}\n`);
34
+ } else {
35
+ console.log(text);
36
+ }
37
+ };
38
+
39
+ async function copyBundledManifest(targetDir) {
40
+ try {
41
+ const sourceManifest = path.join(repoRoot, 'custom-elements.json');
42
+ if (!existsSync(sourceManifest)) {
43
+ log('⚠️ Packaged custom-elements.json not found; skipping manifest copy.', 'yellow');
44
+ return false;
45
+ }
46
+
47
+ if (targetDir) {
48
+ await mkdir(targetDir, { recursive: true });
49
+ const manifestContent = await readFile(sourceManifest, 'utf-8');
50
+ const manifestTarget = path.join(targetDir, 'custom-elements.json');
51
+ await writeFile(manifestTarget, manifestContent, 'utf-8');
52
+ log(`✅ Manifest copied to ${path.relative(process.cwd(), manifestTarget)}`, 'green');
53
+ } else {
54
+ log('✅ Packaged custom-elements.json is available', 'green');
55
+ }
56
+
57
+ const packagedVscodeData = path.join(repoRoot, 'public/assets/pds/vscode-custom-data.json');
58
+ if (targetDir && existsSync(packagedVscodeData)) {
59
+ const vscodeContent = await readFile(packagedVscodeData, 'utf-8');
60
+ const vscodeTarget = path.join(targetDir, 'vscode-custom-data.json');
61
+ await writeFile(vscodeTarget, vscodeContent, 'utf-8');
62
+ log(`✅ VS Code custom data copied to ${path.relative(process.cwd(), vscodeTarget)}`, 'green');
63
+ }
64
+
65
+ return true;
66
+ } catch (error) {
67
+ log(`❌ Failed to copy packaged manifest: ${error?.message || error}`, 'red');
68
+ return false;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Convert Custom Elements Manifest to VS Code Custom Data format
74
+ */
75
+ async function convertToVSCodeFormat(manifest) {
76
+ const tags = [];
77
+
78
+ // Load icon configuration
79
+ let availableIcons = [];
80
+ try {
81
+ const configPath = path.join(repoRoot, 'src/js/pds-core/pds-config.js');
82
+ const { presets } = await import(pathToFileURL(configPath).href);
83
+
84
+ // Get icons from default preset
85
+ const iconConfig = presets?.default?.icons?.include || {};
86
+
87
+ // Extract all icon names from all categories
88
+ availableIcons = Array.from(new Set(
89
+ Object.values(iconConfig).flat()
90
+ )).filter(Boolean).sort();
91
+
92
+ if (availableIcons.length > 0) {
93
+ log(`🎨 Found ${availableIcons.length} icons in configuration`, 'blue');
94
+ }
95
+ } catch (error) {
96
+ log(`⚠️ Could not load icon configuration: ${error.message}`, 'yellow');
97
+ }
98
+
99
+ // Load enhancers for data attribute autocomplete
100
+ let enhancerAttributes = [];
101
+ try {
102
+ const pdsPath = path.join(repoRoot, 'src/js/pds.js');
103
+ const pdsModule = await import(pathToFileURL(pdsPath).href);
104
+ const enhancers = pdsModule?.PDS?.defaultEnhancers || [];
105
+
106
+ for (const enhancer of enhancers) {
107
+ // Extract data-* attributes from selectors
108
+ const selectorMatch = enhancer.selector.match(/\[data-([^\]]+)\]/);
109
+ if (selectorMatch) {
110
+ const attrName = `data-${selectorMatch[1]}`;
111
+ let demoCode = '';
112
+
113
+ // Get demo HTML if available
114
+ if (enhancer.demoHtml) {
115
+ try {
116
+ demoCode = typeof enhancer.demoHtml === 'function'
117
+ ? enhancer.demoHtml()
118
+ : enhancer.demoHtml;
119
+ // Clean up the demo code
120
+ demoCode = demoCode.trim().replace(/\n\s+/g, '\n').replace(/\n{3,}/g, '\n\n');
121
+ } catch (e) {
122
+ demoCode = '';
123
+ }
124
+ }
125
+
126
+ enhancerAttributes.push({
127
+ name: attrName,
128
+ description: enhancer.description || `Progressive enhancement: ${enhancer.selector}`,
129
+ demoCode: demoCode,
130
+ selector: enhancer.selector
131
+ });
132
+ }
133
+ }
134
+
135
+ if (enhancerAttributes.length > 0) {
136
+ log(`🔧 Found ${enhancerAttributes.length} enhancement attributes`, 'blue');
137
+ }
138
+ } catch (error) {
139
+ log(`⚠️ Could not load enhancers: ${error.message}`, 'yellow');
140
+ }
141
+
142
+ manifest.modules?.forEach(module => {
143
+ module.declarations?.forEach(declaration => {
144
+ if (declaration.tagName && declaration.customElement) {
145
+ const tag = {
146
+ name: declaration.tagName,
147
+ description: declaration.description || `${declaration.name} component`
148
+ };
149
+
150
+ // Add attributes
151
+ if (declaration.attributes && declaration.attributes.length > 0) {
152
+ tag.attributes = declaration.attributes.map(attr => {
153
+ const attribute = {
154
+ name: attr.name,
155
+ description: attr.description || ''
156
+ };
157
+
158
+ // Special handling for pds-icon's icon attribute - add available icon names
159
+ if (declaration.tagName === 'pds-icon' && attr.name === 'icon' && availableIcons.length > 0) {
160
+ attribute.values = availableIcons.map(iconName => ({
161
+ name: iconName,
162
+ description: `${iconName} icon`
163
+ }));
164
+ }
165
+ // Check if type indicates enum values
166
+ else if (attr.type?.text) {
167
+ const typeText = attr.type.text;
168
+ // Match patterns like "bottom" | "top" | "left" | "right"
169
+ const enumMatch = typeText.match(/"([^"]+)"/g);
170
+ if (enumMatch && enumMatch.length > 1) {
171
+ attribute.values = enumMatch.map(val => ({ name: val.replace(/"/g, '') }));
172
+ }
173
+ }
174
+
175
+ // Add boolean value set for boolean types
176
+ if (attr.type?.text === 'boolean') {
177
+ attribute.valueSet = 'v';
178
+ }
179
+
180
+ return attribute;
181
+ });
182
+ }
183
+
184
+ tags.push(tag);
185
+ }
186
+ });
187
+ });
188
+
189
+ // Build global attributes for data-* enhancements
190
+ const globalAttributes = enhancerAttributes.map(attr => {
191
+ const description = attr.demoCode
192
+ ? `${attr.description}\n\nExample:\n${attr.demoCode}`
193
+ : attr.description;
194
+
195
+ return {
196
+ name: attr.name,
197
+ description: description,
198
+ valueSet: 'v' // Boolean-like attributes
199
+ };
200
+ });
201
+
202
+ return {
203
+ version: 1.1,
204
+ tags,
205
+ globalAttributes: globalAttributes.length > 0 ? globalAttributes : undefined
206
+ };
207
+ }
208
+
209
+ /**
210
+ * Create pds.html-data.json in project root
211
+ */
212
+ async function createHtmlDataConfig(vscodeDataPath) {
213
+ const config = {
214
+ "html.customData": [vscodeDataPath]
215
+ };
216
+
217
+ const configPath = path.join(repoRoot, 'pds.html-data.json');
218
+ await writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8');
219
+ log(`✅ Created pds.html-data.json`, 'green');
220
+ return configPath;
221
+ }
222
+
223
+ /**
224
+ * Reload VS Code window
225
+ */
226
+ function reloadVSCode() {
227
+ // Note: Automatic reload would require VS Code extension API
228
+ // For now, just inform the user to reload manually
229
+ log('⚠️ Please reload VS Code to activate the updated custom data:', 'yellow');
230
+ log(' Press Ctrl+Shift+P → "Developer: Reload Window"', 'blue');
231
+ }
232
+
233
+ /**
234
+ * Analyze components and generate manifest
235
+ */
236
+ async function generateManifest(targetDir) {
237
+ try {
238
+ log('📋 Generating Custom Elements Manifest...', 'bold');
239
+
240
+ const analyzerInstalled = existsSync(path.join(repoRoot, 'node_modules/@custom-elements-manifest/analyzer'));
241
+ const runningFromPostinstall = process.env.PDS_POSTINSTALL === '1';
242
+
243
+ if (!analyzerInstalled || runningFromPostinstall) {
244
+ if (!analyzerInstalled) {
245
+ const color = runningFromPostinstall ? 'blue' : 'yellow';
246
+ log('ℹ️ Using packaged Custom Elements manifest (analyzer not available).', color);
247
+ if (!runningFromPostinstall) {
248
+ log(' Install @custom-elements-manifest/analyzer to enable manifest regeneration.', 'yellow');
249
+ }
250
+ } else {
251
+ log('ℹ️ Skipping analyzer during postinstall; using packaged manifest.', 'blue');
252
+ }
253
+ return copyBundledManifest(targetDir);
254
+ }
255
+
256
+ // Run the analyzer
257
+ const configPath = path.join(repoRoot, 'custom-elements-manifest.config.js');
258
+
259
+ log('🔍 Analyzing components...', 'blue');
260
+
261
+ try {
262
+ execSync(`npx cem analyze --config ${configPath}`, {
263
+ cwd: repoRoot,
264
+ stdio: 'inherit'
265
+ });
266
+
267
+ // Post-process: Remove private members from the generated manifest
268
+ const sourceManifest = path.join(repoRoot, 'custom-elements.json');
269
+ if (existsSync(sourceManifest)) {
270
+ log('🧹 Cleaning private members from manifest...', 'blue');
271
+ const manifestContent = await readFile(sourceManifest, 'utf-8');
272
+ const manifest = JSON.parse(manifestContent);
273
+
274
+ // Filter out private members from all declarations
275
+ manifest.modules?.forEach(module => {
276
+ module.declarations?.forEach(declaration => {
277
+ if (declaration.members) {
278
+ declaration.members = declaration.members.filter(member => {
279
+ // Keep only public members (exclude private and those starting with #)
280
+ return member.privacy !== 'private' && !member.name?.startsWith('#');
281
+ });
282
+ }
283
+ });
284
+ });
285
+
286
+ // Write cleaned manifest back
287
+ await writeFile(sourceManifest, JSON.stringify(manifest, null, 2), 'utf-8');
288
+ log('✅ Private members removed', 'green');
289
+ }
290
+
291
+ // Copy manifest to target directory if specified
292
+ if (targetDir) {
293
+ const targetManifest = path.join(targetDir, 'custom-elements.json');
294
+
295
+ if (existsSync(sourceManifest)) {
296
+ await mkdir(path.dirname(targetManifest), { recursive: true });
297
+ const manifestContent = await readFile(sourceManifest, 'utf-8');
298
+ await writeFile(targetManifest, manifestContent, 'utf-8');
299
+ log(`✅ Manifest copied to ${path.relative(process.cwd(), targetManifest)}`, 'green');
300
+ }
301
+ }
302
+
303
+ log('✅ Custom Elements Manifest generated', 'green');
304
+
305
+ // Step 1: Generate VS Code custom data file
306
+ log('🔧 Generating VS Code custom data...', 'blue');
307
+ const manifestContent = await readFile(sourceManifest, 'utf-8');
308
+ const manifest = JSON.parse(manifestContent);
309
+ const vscodeData = await convertToVSCodeFormat(manifest);
310
+
311
+ // Write to both locations
312
+ const vscodeDataPath = path.join(repoRoot, 'public/assets/pds/vscode-custom-data.json');
313
+ await mkdir(path.dirname(vscodeDataPath), { recursive: true });
314
+ await writeFile(vscodeDataPath, JSON.stringify(vscodeData, null, 2), 'utf-8');
315
+ log(`✅ VS Code custom data generated at ${path.relative(repoRoot, vscodeDataPath)}`, 'green');
316
+
317
+ // Also copy to target directory if specified
318
+ if (targetDir) {
319
+ const targetVSCodeData = path.join(targetDir, 'vscode-custom-data.json');
320
+ await writeFile(targetVSCodeData, JSON.stringify(vscodeData, null, 2), 'utf-8');
321
+ log(`✅ VS Code custom data copied to ${path.relative(process.cwd(), targetVSCodeData)}`, 'green');
322
+ }
323
+
324
+ // Step 2: Create pds.html-data.json in project root
325
+ const relativePath = 'public/assets/pds/vscode-custom-data.json';
326
+ await createHtmlDataConfig(relativePath);
327
+
328
+ // Step 3: Reload VS Code window
329
+ log('🔄 Reloading VS Code...', 'blue');
330
+ reloadVSCode();
331
+
332
+ return true;
333
+ } catch (error) {
334
+ log(`❌ Manifest generation failed: ${error.message}`, 'red');
335
+ return false;
336
+ }
337
+
338
+ } catch (error) {
339
+ log(`❌ Error: ${error.message}`, 'red');
340
+ return false;
341
+ }
342
+ }
343
+
344
+ export { generateManifest };
345
+
346
+ // Run if called directly
347
+ if (process.argv[1] && process.argv[1].endsWith('generate-manifest.js')) {
348
+ const targetDir = process.argv[2] || null;
349
+ generateManifest(targetDir).then(success => {
350
+ process.exit(success ? 0 : 1);
351
+ });
352
+ }