Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ out
dist
*.tgz

# generated templates archive (created during prepare script)
templates.zip

# code coverage
coverage
*.lcov
Expand Down
6 changes: 6 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 13 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,18 @@
"bin": {
"create-ely": "./src/index.ts"
},
"files": ["src", "templates", "README.md", "LICENSE"],
"files": [
"src",
"templates.zip",
"scripts/postinstall.ts",
"README.md",
"LICENSE"
],
"scripts": {
"dev": "bun run src/index.ts",
"build": "bun build src/index.ts --compile --outfile dist/create-ely"
"build": "bun build src/index.ts --compile --outfile dist/create-ely",
"prepare": "bun run scripts/prepare.ts",
"postinstall": "bun run scripts/postinstall.ts"
},
"engines": {
"bun": ">=1.0.0"
Expand All @@ -51,10 +59,12 @@
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"@clack/prompts": "^0.11.0"
"@clack/prompts": "^0.11.0",
"adm-zip": "^0.5.16"
},
"devDependencies": {
"@biomejs/biome": "2.3.10",
"@types/adm-zip": "^0.5.7",
"@types/bun": "^1.3.5"
}
}
43 changes: 43 additions & 0 deletions scripts/postinstall.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bun
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import AdmZip from 'adm-zip';

/**
* Postinstall script that runs after package installation
* Unzips the templates folder to restore .gitignore files
* See: https://johnnyreilly.com/smuggling-gitignore-npmrc-in-npm-packages
*/
const templatesPath = join(import.meta.dir, '..', 'templates');
const zipPath = join(import.meta.dir, '..', 'templates.zip');

// Skip if templates folder already exists (source repo or already extracted)
if (existsSync(templatesPath)) {
process.exit(0);
}

// Zip file must exist in installed package
if (!existsSync(zipPath)) {
console.error(
'ERROR: templates.zip not found. Installation may be corrupted.',
);
process.exit(1);
}

try {
const zip = new AdmZip(zipPath);
zip.extractAllTo(templatesPath, true);

if (!existsSync(templatesPath)) {
throw new Error('Templates folder was not created after extraction');
}
} catch (error) {
console.error(
'ERROR: Failed to extract templates:',
error instanceof Error ? error.message : error,
);
console.error(
'Report this issue: https://github.com/truehazker/create-ely/issues',
);
process.exit(1);
}
42 changes: 42 additions & 0 deletions scripts/prepare.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bun
import { existsSync, unlinkSync } from 'node:fs';
import { join } from 'node:path';
import AdmZip from 'adm-zip';

/**
* Prepare script that runs before publishing
* Zips the templates folder to preserve .gitignore files
* See: https://johnnyreilly.com/smuggling-gitignore-npmrc-in-npm-packages
*/
const templatesPath = join(import.meta.dir, '..', 'templates');
const zipPath = join(import.meta.dir, '..', 'templates.zip');

// Templates folder must exist
if (!existsSync(templatesPath)) {
console.error('ERROR: templates folder not found. Cannot create archive.');
process.exit(1);
}

try {
// Remove existing zip if it exists
if (existsSync(zipPath)) {
unlinkSync(zipPath);
}

// Create zip archive
const zip = new AdmZip();
zip.addLocalFolder(templatesPath);
zip.writeZip(zipPath);

if (!existsSync(zipPath)) {
throw new Error('templates.zip was not created');
}

console.log('✓ templates.zip created successfully');
} catch (error) {
console.error(
'ERROR: Failed to create templates.zip:',
error instanceof Error ? error.message : error,
);
process.exit(1);
}