@bobfrankston/extractids 1.0.7 → 1.0.9
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 +8 -0
- package/generate-importmap.js +85 -0
- package/index.js +3 -3
- package/package.json +3 -2
- package/.gitattributes +0 -7
- package/.vscode/launch.json +0 -21
- package/.vscode/oldtasks.json +0 -23
- package/.vscode/settings.json +0 -23
- package/.vscode/tasks.json +0 -20
- package/CLAUDE.md +0 -60
- package/index.js.map +0 -1
- package/index.ts +0 -99
- package/tsconfig.json +0 -26
package/README.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
`extractids` is a TypeScript utility that scans your `index.html` and all CSS files in your project to automatically generate type definitions for HTML IDs and CSS classes. These types allow you to perform type-checked DOM and class operations in your code, improving safety and developer experience.
|
|
4
4
|
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
### extractids
|
|
8
|
+
Scans HTML and CSS files to generate TypeScript type definitions.
|
|
9
|
+
|
|
10
|
+
### generate-importmap
|
|
11
|
+
Generates ES Module import maps from package.json dependencies for native browser module loading.
|
|
12
|
+
|
|
5
13
|
## How It Works
|
|
6
14
|
- Scans `index.html` for all `id` attributes.
|
|
7
15
|
- Scans all `.css` files for class names.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Generate ES Module import map from package.json dependencies
|
|
4
|
+
* Injects into HTML files for native browser module loading
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import chokidar from 'chokidar';
|
|
10
|
+
|
|
11
|
+
function generateImportMap(packageJsonPath, htmlFilePath) {
|
|
12
|
+
try {
|
|
13
|
+
// Read package.json
|
|
14
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
15
|
+
const dependencies = packageJson.dependencies || {};
|
|
16
|
+
|
|
17
|
+
// Generate import map
|
|
18
|
+
const imports = {};
|
|
19
|
+
for (const [name, version] of Object.entries(dependencies)) {
|
|
20
|
+
imports[name] = `./node_modules/${name}/index.js`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const importMapScript = `<script type="importmap">
|
|
24
|
+
${JSON.stringify({ imports }, null, 12)}
|
|
25
|
+
</script>`;
|
|
26
|
+
|
|
27
|
+
// Read HTML file
|
|
28
|
+
let html = fs.readFileSync(htmlFilePath, 'utf-8');
|
|
29
|
+
|
|
30
|
+
// Replace import map section
|
|
31
|
+
const importMapRegex = /<!-- Import map.*?-->|<script type="importmap">[\s\S]*?<\/script>/;
|
|
32
|
+
|
|
33
|
+
if (importMapRegex.test(html)) {
|
|
34
|
+
html = html.replace(importMapRegex, importMapScript);
|
|
35
|
+
} else {
|
|
36
|
+
// Insert before </head> if not found
|
|
37
|
+
html = html.replace('</head>', ` ${importMapScript}\n</head>`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Write back to HTML file
|
|
41
|
+
fs.writeFileSync(htmlFilePath, html, 'utf-8');
|
|
42
|
+
|
|
43
|
+
console.log('[generate-importmap] Updated import map');
|
|
44
|
+
console.log(' Dependencies:', Object.keys(dependencies).join(', ') || '(none)');
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.error('[generate-importmap] Error:', e.message);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Parse CLI arguments
|
|
52
|
+
const args = process.argv.slice(2);
|
|
53
|
+
const watchMode = args.includes('-w') || args.includes('--watch');
|
|
54
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
55
|
+
const htmlFilePath = path.join(process.cwd(), 'index.html');
|
|
56
|
+
|
|
57
|
+
// Check if files exist
|
|
58
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
59
|
+
console.error('[generate-importmap] Error: package.json not found in current directory');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
if (!fs.existsSync(htmlFilePath)) {
|
|
63
|
+
console.error('[generate-importmap] Error: index.html not found in current directory');
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (watchMode) {
|
|
68
|
+
generateImportMap(packageJsonPath, htmlFilePath);
|
|
69
|
+
console.log('[generate-importmap] Watching for changes...');
|
|
70
|
+
|
|
71
|
+
const watcher = chokidar.watch([packageJsonPath], {
|
|
72
|
+
persistent: true,
|
|
73
|
+
ignoreInitial: true
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
watcher.on('change', () => generateImportMap(packageJsonPath, htmlFilePath));
|
|
77
|
+
watcher.on('ready', () => {
|
|
78
|
+
console.log('[generate-importmap] Watcher is ready and running.');
|
|
79
|
+
});
|
|
80
|
+
watcher.on('error', (error) => {
|
|
81
|
+
console.error('[generate-importmap] Watcher error:', error.message);
|
|
82
|
+
});
|
|
83
|
+
} else {
|
|
84
|
+
generateImportMap(packageJsonPath, htmlFilePath);
|
|
85
|
+
}
|
package/index.js
CHANGED
|
@@ -49,10 +49,10 @@ function globReadCssFiles() {
|
|
|
49
49
|
}
|
|
50
50
|
function generateTypes(ids, classes) {
|
|
51
51
|
const idType = ids.length > 0
|
|
52
|
-
? `export type htmlIDs = ${ids.map(id => `"${id}"`).join('
|
|
52
|
+
? `export type htmlIDs = ${ids.map(id => `"${id}"`).join(' |\n')};\n`
|
|
53
53
|
: `export type htmlIDs = never;\n`;
|
|
54
54
|
const classType = classes.length > 0
|
|
55
|
-
? `export type cssClasses = ${classes.map(cls => `"${cls}"`).join('
|
|
55
|
+
? `export type cssClasses = ${classes.map(cls => `"${cls}"`).join(' |\n')};\n`
|
|
56
56
|
: `export type cssClasses = never;\n`;
|
|
57
57
|
return idType + classType;
|
|
58
58
|
}
|
|
@@ -71,7 +71,7 @@ function updateTypesFile() {
|
|
|
71
71
|
}
|
|
72
72
|
// Parse CLI arguments for -w or --watch
|
|
73
73
|
const args = process.argv.slice(2);
|
|
74
|
-
const watchMode = args.includes('-w') || args.includes('--watch');
|
|
74
|
+
const watchMode = args.includes('-w') || args.includes('-watch') || args.includes('--watch');
|
|
75
75
|
if (watchMode) {
|
|
76
76
|
updateTypesFile();
|
|
77
77
|
console.log('[extractids] Watching for changes...');
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bobfrankston/extractids",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Extracd html and css as types",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"extractids": "index.js"
|
|
7
|
+
"extractids": "index.js",
|
|
8
|
+
"generate-importmap": "generate-importmap.js"
|
|
8
9
|
},
|
|
9
10
|
"module": "main.js",
|
|
10
11
|
"scripts": {
|
package/.gitattributes
DELETED
package/.vscode/launch.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Use IntelliSense to learn about possible attributes.
|
|
3
|
-
// Hover to view descriptions of existing attributes.
|
|
4
|
-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
-
"version": "0.2.0",
|
|
6
|
-
"configurations": [
|
|
7
|
-
{
|
|
8
|
-
"type": "node",
|
|
9
|
-
"request": "launch",
|
|
10
|
-
"name": "Launch Program",
|
|
11
|
-
"program": "${workspaceFolder}/index.js",
|
|
12
|
-
"skipFiles": [
|
|
13
|
-
"<node_internals>/**"
|
|
14
|
-
],
|
|
15
|
-
"outFiles": [
|
|
16
|
-
"${workspaceFolder}/**/*.js"
|
|
17
|
-
],
|
|
18
|
-
"cwd": "y:\\x\\bin\\WallClock"
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
}
|
package/.vscode/oldtasks.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Template 1.0 y:\x\bin\MakeCodeTemplates\vscode\
|
|
3
|
-
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
|
4
|
-
// for the documentation about the tasks.json format
|
|
5
|
-
"version": "2.0.0",
|
|
6
|
-
"tasks": [
|
|
7
|
-
{
|
|
8
|
-
"type": "typescript",
|
|
9
|
-
"tsconfig": "tsconfig.json",
|
|
10
|
-
"option": "watch",
|
|
11
|
-
"runOptions": {
|
|
12
|
-
"runOn": "folderOpen"
|
|
13
|
-
},
|
|
14
|
-
"problemMatcher": [
|
|
15
|
-
"$tsc-watch"
|
|
16
|
-
],
|
|
17
|
-
"group": {
|
|
18
|
-
"kind": "build",
|
|
19
|
-
"isDefault": true
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}
|
package/.vscode/settings.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"workbench.colorCustomizations": {
|
|
3
|
-
"activityBar.activeBackground": "#588e2f",
|
|
4
|
-
"activityBar.background": "#588e2f",
|
|
5
|
-
"activityBar.foreground": "#e7e7e7",
|
|
6
|
-
"activityBar.inactiveForeground": "#e7e7e799",
|
|
7
|
-
"activityBarBadge.background": "#284a78",
|
|
8
|
-
"activityBarBadge.foreground": "#e7e7e7",
|
|
9
|
-
"commandCenter.border": "#e7e7e799",
|
|
10
|
-
"sash.hoverBorder": "#588e2f",
|
|
11
|
-
"statusBar.background": "#406822",
|
|
12
|
-
"statusBar.foreground": "#e7e7e7",
|
|
13
|
-
"statusBarItem.hoverBackground": "#588e2f",
|
|
14
|
-
"statusBarItem.remoteBackground": "#406822",
|
|
15
|
-
"statusBarItem.remoteForeground": "#e7e7e7",
|
|
16
|
-
"titleBar.activeBackground": "#406822",
|
|
17
|
-
"titleBar.activeForeground": "#e7e7e7",
|
|
18
|
-
"titleBar.inactiveBackground": "#40682299",
|
|
19
|
-
"titleBar.inactiveForeground": "#e7e7e799"
|
|
20
|
-
},
|
|
21
|
-
"peacock.color": "#406822",
|
|
22
|
-
"workbench.colorTheme": "Visual Studio 2019 Dark"
|
|
23
|
-
}
|
package/.vscode/tasks.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "2.0.0",
|
|
3
|
-
"tasks": [
|
|
4
|
-
{
|
|
5
|
-
"label": "tsc: watch",
|
|
6
|
-
"type": "shell",
|
|
7
|
-
"command": "tsc",
|
|
8
|
-
"args": ["--watch"],
|
|
9
|
-
"runOptions": {
|
|
10
|
-
"runOn": "folderOpen"
|
|
11
|
-
},
|
|
12
|
-
"problemMatcher": "$tsc-watch",
|
|
13
|
-
"isBackground": true,
|
|
14
|
-
"group": {
|
|
15
|
-
"kind": "build",
|
|
16
|
-
"isDefault": true
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
]
|
|
20
|
-
}
|
package/CLAUDE.md
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# CLAUDE.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
`extractids` is a TypeScript CLI utility that extracts HTML IDs and CSS class names to generate TypeScript type definitions. The tool scans `index.html` and all `.css` files in a project to create a `generated-types.ts` file with type-safe DOM and styling operations.
|
|
7
|
-
|
|
8
|
-
## Architecture
|
|
9
|
-
- **Single-file architecture**: Main functionality in `index.ts`
|
|
10
|
-
- **Entry point**: `index.js` (compiled from `index.ts`) serves as both CLI binary and main module
|
|
11
|
-
- **Type generation**: Produces `generated-types.ts` with `htmlIDs` and `cssClasses` union types
|
|
12
|
-
- **File scanning**: Uses cheerio for HTML parsing and regex for CSS class extraction
|
|
13
|
-
- **Watch mode**: Uses chokidar for file system watching
|
|
14
|
-
|
|
15
|
-
## Development Commands
|
|
16
|
-
|
|
17
|
-
### Build
|
|
18
|
-
```bash
|
|
19
|
-
tsc
|
|
20
|
-
```
|
|
21
|
-
Compiles TypeScript to JavaScript using the tsconfig.json configuration.
|
|
22
|
-
|
|
23
|
-
### Run locally
|
|
24
|
-
```bash
|
|
25
|
-
node index.js
|
|
26
|
-
# or with watch mode
|
|
27
|
-
node index.js -w
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### Test the CLI
|
|
31
|
-
```bash
|
|
32
|
-
# Install globally for testing
|
|
33
|
-
npm install -g .
|
|
34
|
-
extractids
|
|
35
|
-
extractids -w
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Key Components
|
|
39
|
-
|
|
40
|
-
### Core Functions
|
|
41
|
-
- `getHtmlIDs(html)`: Parses HTML with cheerio to extract ID attributes
|
|
42
|
-
- `getCssClasses(css)`: Uses regex `/\.([a-zA-Z0-9_-]+)\s*[{,]/g` to extract CSS class names
|
|
43
|
-
- `globReadCssFiles()`: Recursively finds all `.css` files while ignoring `node_modules`
|
|
44
|
-
- `generateTypes()`: Creates TypeScript union types from extracted IDs and classes
|
|
45
|
-
- `updateTypesFile()`: Main orchestration function that combines all operations
|
|
46
|
-
|
|
47
|
-
### File Dependencies
|
|
48
|
-
- Expects `index.html` in the current working directory
|
|
49
|
-
- Scans all `.css` files recursively from current directory
|
|
50
|
-
- Outputs `generated-types.ts` in current directory
|
|
51
|
-
|
|
52
|
-
### CLI Options
|
|
53
|
-
- `-w` or `--watch`: Enables file system watching for automatic regeneration
|
|
54
|
-
- No arguments: Single-run mode that generates types once
|
|
55
|
-
|
|
56
|
-
## TypeScript Configuration
|
|
57
|
-
- Target: ESNext with NodeNext module resolution
|
|
58
|
-
- Source maps enabled for debugging
|
|
59
|
-
- Strict type checking with some relaxed settings (`strictNullChecks: false`)
|
|
60
|
-
- Includes all `.ts` files, excludes `node_modules`
|
package/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
package/index.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// scripts/generateTypes.ts
|
|
3
|
-
import * as fs from 'node:fs';
|
|
4
|
-
import * as path from 'node:path';
|
|
5
|
-
import * as cheerio from 'cheerio';
|
|
6
|
-
import chokidar from 'chokidar';
|
|
7
|
-
// import * as glob from 'glob';
|
|
8
|
-
|
|
9
|
-
// Helper function to extract all id attributes from HTML
|
|
10
|
-
function getHtmlIDs(html: string) {
|
|
11
|
-
const $ = cheerio.load(html);
|
|
12
|
-
const ids = new Set<string>();
|
|
13
|
-
$('[id]').each((_, elem) => {
|
|
14
|
-
const id = $(elem).attr('id');
|
|
15
|
-
if (id) ids.add(id);
|
|
16
|
-
});
|
|
17
|
-
return Array.from(ids).sort();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Helper function to extract all class names from CSS files
|
|
21
|
-
function getCssClasses(css: string) {
|
|
22
|
-
// Match any .classname { or .classname,
|
|
23
|
-
const classPattern = /\.([a-zA-Z0-9_-]+)\s*[{,]/g;
|
|
24
|
-
const classes = new Set<string>();
|
|
25
|
-
let match: RegExpExecArray | null;
|
|
26
|
-
while ((match = classPattern.exec(css))) {
|
|
27
|
-
classes.add(match[1]);
|
|
28
|
-
}
|
|
29
|
-
return Array.from(classes).sort();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
function globReadCssFiles(): string[] {
|
|
34
|
-
// Recursively find all .css files in project folder, ignoring node_modules
|
|
35
|
-
const result: string[] = [];
|
|
36
|
-
function walk(dir: string) {
|
|
37
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
38
|
-
for (const entry of entries) {
|
|
39
|
-
const fullPath = path.join(dir, entry.name);
|
|
40
|
-
if (entry.isDirectory()) {
|
|
41
|
-
if (entry.name === 'node_modules') continue;
|
|
42
|
-
walk(fullPath);
|
|
43
|
-
} else if (entry.isFile() && fullPath.endsWith('.css')) {
|
|
44
|
-
result.push(fullPath);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
walk(process.cwd());
|
|
49
|
-
return result;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function generateTypes(ids: string[], classes: string[]) {
|
|
53
|
-
const idType =
|
|
54
|
-
ids.length > 0
|
|
55
|
-
? `export type htmlIDs = ${ids.map(id => `"${id}"`).join(' | ')};\n`
|
|
56
|
-
: `export type htmlIDs = never;\n`;
|
|
57
|
-
const classType =
|
|
58
|
-
classes.length > 0
|
|
59
|
-
? `export type cssClasses = ${classes.map(cls => `"${cls}"`).join(' | ')};\n`
|
|
60
|
-
: `export type cssClasses = never;\n`;
|
|
61
|
-
return idType + classType;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function updateTypesFile() {
|
|
65
|
-
const html = fs.readFileSync('index.html', 'utf8');
|
|
66
|
-
const ids = getHtmlIDs(html);
|
|
67
|
-
|
|
68
|
-
const cssFiles = globReadCssFiles();
|
|
69
|
-
const allClasses = new Set<string>();
|
|
70
|
-
cssFiles.forEach(file => {
|
|
71
|
-
const css = fs.readFileSync(file, 'utf8');
|
|
72
|
-
getCssClasses(css).forEach(cls => allClasses.add(cls));
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const types = generateTypes(ids, Array.from(allClasses));
|
|
76
|
-
fs.writeFileSync('generated-types.ts', types);
|
|
77
|
-
console.log('[Type generation] Updated generated-types.ts');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// Parse CLI arguments for -w or --watch
|
|
82
|
-
const args = process.argv.slice(2);
|
|
83
|
-
const watchMode = args.includes('-w') || args.includes('--watch');
|
|
84
|
-
|
|
85
|
-
if (watchMode) {
|
|
86
|
-
updateTypesFile();
|
|
87
|
-
console.log('[extractids] Watching for changes...');
|
|
88
|
-
const watcher = chokidar.watch(['index.html', '**/*.css'], { ignored: /node_modules/ });
|
|
89
|
-
watcher.on('change', () => updateTypesFile());
|
|
90
|
-
watcher.on('ready', () => {
|
|
91
|
-
console.log('[extractids] Watcher is ready and running.');
|
|
92
|
-
});
|
|
93
|
-
watcher.on('error', (error:any) => {
|
|
94
|
-
console.error('[extractids] Watcher error:', error.message);
|
|
95
|
-
});
|
|
96
|
-
// No need for setInterval; watcher should keep process alive
|
|
97
|
-
} else {
|
|
98
|
-
updateTypesFile();
|
|
99
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "esnext",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
// "allowImportingTsExtensions": true,
|
|
7
|
-
"sourceMap": true,
|
|
8
|
-
// "noEmit": true,
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"strict": true,
|
|
12
|
-
"noImplicitAny": true,
|
|
13
|
-
"noImplicitReturns": false,
|
|
14
|
-
"noImplicitThis": true,
|
|
15
|
-
"strictBindCallApply": true,
|
|
16
|
-
"strictFunctionTypes": true,
|
|
17
|
-
"strictNullChecks": false,
|
|
18
|
-
"skipLibCheck": true
|
|
19
|
-
},
|
|
20
|
-
"include": [
|
|
21
|
-
"**/*.ts"
|
|
22
|
-
],
|
|
23
|
-
"exclude": [
|
|
24
|
-
"node_modules",
|
|
25
|
-
]
|
|
26
|
-
}
|