mcp-searchable 1.0.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.
@@ -0,0 +1,188 @@
1
+ # Bootstrap Script
2
+
3
+ This directory contains the bootstrap script for setting up new projects from this template.
4
+
5
+ ## Usage
6
+
7
+ ### Quick Start
8
+
9
+ Bootstrap a new project in the current directory:
10
+
11
+ ```bash
12
+ npx --yes --package=github:templ-project/typescript bootstrap
13
+ ```
14
+
15
+ ### Options
16
+
17
+ #### `--part-of-monorepo`
18
+
19
+ Use this flag when adding this template as part of a monorepo. This will:
20
+
21
+ - Remove `.husky` directory (git hooks)
22
+ - Remove `.github` directory (CI/CD workflows)
23
+ - Remove `husky` and `lint-staged` from dependencies
24
+ - Remove `prepare` script from package.json
25
+ - Remove `lint-staged` configuration
26
+
27
+ ```bash
28
+ npx --yes --package=github:templ-project/typescript bootstrap --part-of-monorepo
29
+ ```
30
+
31
+ #### `--target <targets>`
32
+
33
+ Specify which build targets to keep. By default, all build targets are kept.
34
+
35
+ Available targets:
36
+
37
+ - `all` - Keep all build targets (default)
38
+ - `esm` - ES Modules build
39
+ - `cjs` - CommonJS build
40
+ - `browser` - Browser-specific ESM build
41
+ - `iife` - Immediately Invoked Function Expression build for browsers
42
+
43
+ Multiple targets can be specified as comma-separated values:
44
+
45
+ ```bash
46
+ # Keep only ESM and CJS builds
47
+ npx --yes --package=github:templ-project/typescript bootstrap --target esm,cjs
48
+
49
+ # Keep only browser builds
50
+ npx --yes --package=github:templ-project/typescript bootstrap --target browser,iife
51
+ ```
52
+
53
+ #### Target Directory
54
+
55
+ Specify a target directory as the last argument:
56
+
57
+ ```bash
58
+ npx --yes --package=github:templ-project/typescript bootstrap ./my-project
59
+ ```
60
+
61
+ ### Complete Examples
62
+
63
+ **Standard project in current directory:**
64
+
65
+ ```bash
66
+ npx --yes --package=github:templ-project/typescript bootstrap
67
+ ```
68
+
69
+ **Monorepo package with only ESM and CJS:**
70
+
71
+ ```bash
72
+ npx --yes --package=github:templ-project/typescript bootstrap \
73
+ --part-of-monorepo \
74
+ --target esm,cjs \
75
+ ./packages/my-lib
76
+ ```
77
+
78
+ **Browser-only library:**
79
+
80
+ ```bash
81
+ npx --yes --package=github:templ-project/typescript bootstrap \
82
+ --target browser,iife \
83
+ ./my-browser-lib
84
+ ```
85
+
86
+ ## What the Bootstrap Script Does
87
+
88
+ The bootstrap script performs the following actions:
89
+
90
+ 1. **Clones the Template Repository**
91
+ - Clones from `https://github.com/templ-project/typescript`
92
+ - Uses `--depth 1` for faster cloning
93
+
94
+ 2. **Removes Git History**
95
+ - Deletes `.git` directory to start fresh
96
+
97
+ 3. **Cleans Build Configuration** (if `--target` specified)
98
+ - Removes unwanted build scripts from package.json
99
+ - Keeps only the specified build targets
100
+
101
+ 4. **Removes Bootstrap Artifacts**
102
+ - Deletes `.npx-install` directory (this directory!)
103
+ - Removes `bin` field from package.json
104
+
105
+ 5. **Updates Package Metadata**
106
+ - Resets package name to `my-typescript-project`
107
+ - Resets version to `0.1.0`
108
+ - Clears repository, bugs, and homepage URLs
109
+
110
+ 6. **Monorepo Cleanup** (if `--part-of-monorepo` specified)
111
+ - Removes `.husky` directory
112
+ - Removes `.github` directory
113
+ - Removes git hook dependencies
114
+ - Removes related scripts
115
+
116
+ ## After Bootstrap
117
+
118
+ After running the bootstrap script, follow these steps:
119
+
120
+ 1. **Update package.json**
121
+
122
+ ```bash
123
+ # Edit package.json and update:
124
+ # - name
125
+ # - description
126
+ # - author
127
+ # - repository
128
+ # - homepage
129
+ # - bugs
130
+ ```
131
+
132
+ 2. **Install dependencies**
133
+
134
+ ```bash
135
+ npm install
136
+ ```
137
+
138
+ 3. **Initialize git** (if not part of monorepo)
139
+
140
+ ```bash
141
+ git init
142
+ git add .
143
+ git commit -m "Initial commit from template"
144
+ ```
145
+
146
+ 4. **Run tests**
147
+
148
+ ```bash
149
+ npm test
150
+ ```
151
+
152
+ 5. **Start developing!**
153
+ ```bash
154
+ npm run start
155
+ ```
156
+
157
+ ## Development
158
+
159
+ If you need to modify the bootstrap script:
160
+
161
+ 1. Edit `.npx-install/bootstrap.js`
162
+ 2. Test locally by running:
163
+ ```bash
164
+ node .npx-install/bootstrap.js [options]
165
+ ```
166
+ 3. Commit and push changes to the template repository
167
+
168
+ ## Troubleshooting
169
+
170
+ ### Script Not Found
171
+
172
+ If you get "script not found" errors, ensure:
173
+
174
+ 1. You're using Node.js 20 or higher
175
+ 2. The package was installed correctly
176
+ 3. The `.npx-install/bootstrap.js` file has execute permissions
177
+
178
+ ### Package.json Not Found
179
+
180
+ The bootstrap script clones the template repository first, then modifies it. If you see this error, there may be network issues preventing the clone.
181
+
182
+ ### Permission Errors
183
+
184
+ On Unix-like systems, ensure the bootstrap script is executable:
185
+
186
+ ```bash
187
+ chmod +x .npx-install/bootstrap.js
188
+ ```
@@ -0,0 +1,341 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @fileoverview Bootstrap script for TypeScript template project.
5
+ * Clones the template and prepares it for use as a new project.
6
+ */
7
+
8
+ import { execSync } from 'node:child_process';
9
+ import fs from 'node:fs';
10
+ import path from 'node:path';
11
+
12
+ /**
13
+ * Parses command line arguments.
14
+ * @return {{
15
+ * targetPath: string,
16
+ * partOfMultiRepo: boolean,
17
+ * buildTargets: !Array<string>,
18
+ * help: boolean
19
+ * }} Parsed arguments.
20
+ */
21
+ function parseArgs() {
22
+ const args = process.argv.slice(2);
23
+ const config = {
24
+ targetPath: process.cwd(),
25
+ partOfMultiRepo: false,
26
+ buildTargets: ['all'],
27
+ help: false,
28
+ };
29
+
30
+ for (let i = 0; i < args.length; i++) {
31
+ const arg = args[i];
32
+
33
+ if (arg === '--help' || arg === '-h') {
34
+ config.help = true;
35
+ } else if (arg === '--part-of-monorepo') {
36
+ config.partOfMultiRepo = true;
37
+ } else if (arg === '--target' && i + 1 < args.length) {
38
+ config.buildTargets = args[++i].split(',');
39
+ } else if (!arg.startsWith('--')) {
40
+ config.targetPath = path.resolve(arg);
41
+ }
42
+ }
43
+
44
+ return config;
45
+ }
46
+
47
+ /**
48
+ * Displays help information.
49
+ */
50
+ function showHelp() {
51
+ console.log(`
52
+ TypeScript Template Bootstrap Tool
53
+
54
+ Usage:
55
+ npx --yes --package=github:templ-project/typescript bootstrap [options] [path]
56
+
57
+ Options:
58
+ --part-of-monorepo Remove .husky, .github folders and related packages
59
+ --target <targets> Specify build targets (comma-separated)
60
+ Values: all|esm|cjs|browser
61
+ Default: all
62
+ -h, --help Show this help message
63
+
64
+ Arguments:
65
+ path Target directory (default: current directory)
66
+
67
+ Examples:
68
+ # Bootstrap in current directory with all build targets
69
+ npx --yes --package=github:templ-project/typescript bootstrap
70
+
71
+ # Bootstrap in specific directory
72
+ npx --yes --package=github:templ-project/typescript bootstrap ./my-project
73
+
74
+ # Bootstrap as part of monorepo (removes git hooks)
75
+ npx --yes --package=github:templ-project/typescript bootstrap --part-of-monorepo
76
+
77
+ # Bootstrap with only ESM and CJS builds
78
+ npx --yes --package=github:templ-project/typescript bootstrap --target esm,cjs
79
+
80
+ # Combine options
81
+ npx --yes --package=github:templ-project/typescript bootstrap --part-of-monorepo --target esm ./my-lib
82
+ `);
83
+ }
84
+
85
+ /**
86
+ * Removes a directory or file if it exists.
87
+ * @param {string} targetPath Path to remove.
88
+ */
89
+ function removeIfExists(targetPath) {
90
+ if (fs.existsSync(targetPath)) {
91
+ fs.rmSync(targetPath, { recursive: true, force: true });
92
+ console.log(` āœ“ Removed: ${path.basename(targetPath)}`);
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Reads and parses package.json.
98
+ * @param {string} packagePath Path to package.json.
99
+ * @return {!Object} Parsed package.json.
100
+ */
101
+ function readPackageJson(packagePath) {
102
+ const content = fs.readFileSync(packagePath, 'utf8');
103
+ return JSON.parse(content);
104
+ }
105
+
106
+ /**
107
+ * Writes package.json.
108
+ * @param {string} packagePath Path to package.json.
109
+ * @param {!Object} data Package data.
110
+ */
111
+ function writePackageJson(packagePath, data) {
112
+ fs.writeFileSync(packagePath, JSON.stringify(data, null, 2) + '\n');
113
+ }
114
+
115
+ /**
116
+ * Cleans build scripts based on target configuration.
117
+ * @param {!Object} pkg Package.json object.
118
+ * @param {!Array<string>} buildTargets Target build types.
119
+ * @return {!Object} Modified package.json object.
120
+ */
121
+ function cleanBuildScripts(pkg, buildTargets) {
122
+ if (buildTargets.includes('all')) {
123
+ return pkg;
124
+ }
125
+
126
+ const buildScriptMap = {
127
+ esm: 'build:esm',
128
+ cjs: 'build:cjs',
129
+ browser: 'build:browser',
130
+ iife: 'build:iife',
131
+ };
132
+
133
+ const scriptsToKeep = buildTargets.map((target) => buildScriptMap[target]).filter(Boolean);
134
+
135
+ // Remove unwanted build scripts
136
+ for (const key of Object.keys(pkg.scripts)) {
137
+ if (key.startsWith('build:') && !scriptsToKeep.includes(key)) {
138
+ delete pkg.scripts[key];
139
+ console.log(` āœ“ Removed script: ${key}`);
140
+ }
141
+ }
142
+
143
+ return pkg;
144
+ }
145
+
146
+ /**
147
+ * Removes monorepo-related dependencies.
148
+ * @param {!Object} pkg Package.json object.
149
+ * @return {!Object} Modified package.json object.
150
+ */
151
+ function removeMonorepoDependencies(pkg) {
152
+ const monorepoDeps = ['husky', 'lint-staged'];
153
+
154
+ for (const dep of monorepoDeps) {
155
+ if (pkg.devDependencies && pkg.devDependencies[dep]) {
156
+ delete pkg.devDependencies[dep];
157
+ console.log(` āœ“ Removed dependency: ${dep}`);
158
+ }
159
+ }
160
+
161
+ // Remove lint-staged configuration
162
+ if (pkg['lint-staged']) {
163
+ delete pkg['lint-staged'];
164
+ console.log(` āœ“ Removed lint-staged configuration`);
165
+ }
166
+
167
+ // Remove prepare script (used by husky)
168
+ if (pkg.scripts && pkg.scripts.prepare) {
169
+ delete pkg.scripts.prepare;
170
+ console.log(` āœ“ Removed prepare script`);
171
+ }
172
+
173
+ return pkg;
174
+ }
175
+
176
+ /**
177
+ * Removes bootstrap-related files and dependencies.
178
+ * @param {!Object} pkg Package.json object.
179
+ * @param {string} targetPath Target directory path.
180
+ * @return {!Object} Modified package.json object.
181
+ */
182
+ function removeBootstrapArtifacts(pkg, targetPath) {
183
+ // Remove .npx-install directory
184
+ const installDir = path.join(targetPath, '.npx-install');
185
+ removeIfExists(installDir);
186
+
187
+ // Remove bin field if it exists
188
+ if (pkg.bin) {
189
+ delete pkg.bin;
190
+ console.log(` āœ“ Removed bin configuration`);
191
+ }
192
+
193
+ return pkg;
194
+ }
195
+
196
+ /**
197
+ * Updates package.json metadata for new project.
198
+ * @param {!Object} pkg Package.json object.
199
+ * @return {!Object} Modified package.json object.
200
+ */
201
+ function updatePackageMetadata(pkg) {
202
+ // Reset name to a placeholder
203
+ pkg.name = 'my-typescript-project';
204
+
205
+ // Reset version
206
+ pkg.version = '0.1.0';
207
+
208
+ // Clear repository information
209
+ if (pkg.repository) {
210
+ pkg.repository = {
211
+ type: 'git',
212
+ url: '',
213
+ };
214
+ }
215
+
216
+ // Clear bugs URL
217
+ if (pkg.bugs) {
218
+ pkg.bugs = {
219
+ url: '',
220
+ };
221
+ }
222
+
223
+ // Clear homepage
224
+ if (pkg.homepage) {
225
+ pkg.homepage = '';
226
+ }
227
+
228
+ console.log(` āœ“ Updated package metadata`);
229
+ return pkg;
230
+ }
231
+
232
+ /**
233
+ * Clones the template repository to target directory.
234
+ * @param {string} targetPath Target directory.
235
+ */
236
+ function cloneTemplate(targetPath) {
237
+ console.log('šŸ“ Cloning template repository...\n');
238
+
239
+ // Ensure target directory exists
240
+ if (!fs.existsSync(targetPath)) {
241
+ fs.mkdirSync(targetPath, { recursive: true });
242
+ }
243
+
244
+ // Check if directory is empty
245
+ const files = fs.readdirSync(targetPath);
246
+ if (files.length > 0) {
247
+ console.error('āŒ Error: Target directory is not empty');
248
+ console.error(` Directory: ${targetPath}`);
249
+ console.error(' Please use an empty directory or remove existing files.');
250
+ process.exit(1);
251
+ }
252
+
253
+ try {
254
+ // Clone the repository
255
+ console.log(' Cloning from https://github.com/templ-project/typescript...');
256
+ execSync(`git clone --depth 1 https://github.com/templ-project/typescript.git "${targetPath}"`, {
257
+ stdio: 'pipe',
258
+ });
259
+ console.log(` āœ“ Template cloned to ${targetPath}`);
260
+ } catch (error) {
261
+ console.error('āŒ Error: Failed to clone repository');
262
+ console.error(` ${error.message}`);
263
+ console.error('\nPlease ensure:');
264
+ console.error(' 1. Git is installed and available in PATH');
265
+ console.error(' 2. You have internet connectivity');
266
+ console.error(' 3. You have access to https://github.com/templ-project/typescript');
267
+ process.exit(1);
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Main bootstrap function.
273
+ * @param {{
274
+ * targetPath: string,
275
+ * partOfMultiRepo: boolean,
276
+ * buildTargets: !Array<string>,
277
+ * help: boolean
278
+ * }} config Configuration object.
279
+ */
280
+ function bootstrap(config) {
281
+ if (config.help) {
282
+ showHelp();
283
+ return;
284
+ }
285
+
286
+ console.log('\nšŸš€ TypeScript Template Bootstrap\n');
287
+
288
+ const targetPath = config.targetPath;
289
+
290
+ // Clone template repository to target directory
291
+ cloneTemplate(targetPath);
292
+
293
+ const packagePath = path.join(targetPath, 'package.json');
294
+
295
+ // Now verify package.json exists (it should after copying)
296
+ if (!fs.existsSync(packagePath)) {
297
+ console.error('āŒ Error: Failed to copy template files');
298
+ console.error(` Expected package.json at: ${packagePath}`);
299
+ process.exit(1);
300
+ }
301
+
302
+ console.log('šŸ“¦ Cleaning up template artifacts...\n');
303
+
304
+ // Remove .git directory
305
+ const gitDir = path.join(targetPath, '.git');
306
+ removeIfExists(gitDir);
307
+
308
+ // Handle monorepo-specific cleanup
309
+ if (config.partOfMultiRepo) {
310
+ console.log('\nšŸ¢ Monorepo mode: removing git hooks and CI...\n');
311
+ const huskyDir = path.join(targetPath, '.husky');
312
+ const githubDir = path.join(targetPath, '.github');
313
+ removeIfExists(huskyDir);
314
+ removeIfExists(githubDir);
315
+ }
316
+
317
+ // Update package.json
318
+ console.log('\nšŸ“ Updating package.json...\n');
319
+ let pkg = readPackageJson(packagePath);
320
+
321
+ pkg = cleanBuildScripts(pkg, config.buildTargets);
322
+ pkg = removeBootstrapArtifacts(pkg, targetPath);
323
+ pkg = updatePackageMetadata(pkg);
324
+
325
+ if (config.partOfMultiRepo) {
326
+ pkg = removeMonorepoDependencies(pkg);
327
+ }
328
+
329
+ writePackageJson(packagePath, pkg);
330
+
331
+ console.log('\n✨ Bootstrap complete!\n');
332
+ console.log('Next steps:');
333
+ console.log(' 1. Update package.json name, description, and repository');
334
+ console.log(' 2. Run: npm install');
335
+ console.log(' 3. Run: npm test');
336
+ console.log(' 4. Start coding!\n');
337
+ }
338
+
339
+ // Run the bootstrap
340
+ const config = parseArgs();
341
+ bootstrap(config);
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Templ Project
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.