Skip to content

Commit d30a937

Browse files
committed
fix: add checksums to the framework content packages
1 parent 7b7c373 commit d30a937

File tree

8 files changed

+164
-0
lines changed

8 files changed

+164
-0
lines changed

frameworks/react-cra/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"main": "./dist/index.js",
77
"types": "./dist/types/index.d.ts",
88
"scripts": {
9+
"prebuild": "node ../../scripts/generate-checksums.js",
910
"build": "tsc",
1011
"dev": "tsc --watch",
1112
"test": "eslint ./src && vitest run",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This file is auto-generated. Do not edit manually.
2+
// Generated from add-ons, examples, hosts, project, and toolchains directories
3+
export const contentChecksum = '2bc5d6d1275fc866a1561719c657003610a9c50e837678758f63632b4eea34a0'

frameworks/react-cra/src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import {
66
scanAddOnDirectories,
77
scanProjectDirectory,
88
} from '@tanstack/cta-engine'
9+
10+
import { contentChecksum } from './checksum'
11+
912
import type { FrameworkDefinition } from '@tanstack/cta-engine'
1013

1114
export function createFrameworkDefinition(): FrameworkDefinition {
@@ -50,3 +53,5 @@ export function createFrameworkDefinition(): FrameworkDefinition {
5053
export function register() {
5154
registerFramework(createFrameworkDefinition())
5255
}
56+
57+
export { contentChecksum }

frameworks/solid/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"main": "./dist/index.js",
77
"types": "./dist/types/index.d.ts",
88
"scripts": {
9+
"prebuild": "node ../../scripts/generate-checksums.js",
910
"build": "tsc",
1011
"dev": "tsc --watch",
1112
"test": "eslint ./src && vitest run",

frameworks/solid/src/checksum.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This file is auto-generated. Do not edit manually.
2+
// Generated from add-ons, examples, hosts, project, and toolchains directories
3+
export const contentChecksum = 'c7f773b3a7dfae74eefe6c1aabefef523827058f72cc9dc2f8c37a3df3d0933d'

frameworks/solid/src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import {
66
scanAddOnDirectories,
77
scanProjectDirectory,
88
} from '@tanstack/cta-engine'
9+
10+
import { contentChecksum } from './checksum'
11+
912
import type { FrameworkDefinition } from '@tanstack/cta-engine'
1013

1114
export function createFrameworkDefinition(): FrameworkDefinition {
@@ -50,3 +53,5 @@ export function createFrameworkDefinition(): FrameworkDefinition {
5053
export function register() {
5154
registerFramework(createFrameworkDefinition())
5255
}
56+
57+
export { contentChecksum }

scripts/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Scripts
2+
3+
## generate-checksums.js
4+
5+
This script generates checksums for the `react-cra` and `solid` frameworks to ensure version bumps when content changes.
6+
7+
### Purpose
8+
9+
The checksum system ensures that when any files in the following directories change, the framework package will have a different build output, triggering proper version bumping:
10+
11+
- `add-ons/`
12+
- `examples/`
13+
- `hosts/`
14+
- `project/`
15+
- `toolchains/`
16+
17+
### How It Works
18+
19+
1. The script recursively scans all files in the specified directories
20+
2. Calculates a SHA-256 hash of all file contents and paths
21+
3. Generates `src/checksum.ts` in each framework with the exported checksum value
22+
4. The checksum is exported from `src/index.ts` and included in the built output
23+
24+
### Integration
25+
26+
The checksum generation runs automatically before each build via the `prebuild` script in:
27+
28+
- `frameworks/react-cra/package.json`
29+
- `frameworks/solid/package.json`
30+
31+
When running `pnpm build` at the root level, the checksums are automatically regenerated for both frameworks before TypeScript compilation.
32+
33+
### Generated Files
34+
35+
- `frameworks/react-cra/src/checksum.ts`
36+
- `frameworks/solid/src/checksum.ts`
37+
38+
**Note:** These generated files should be committed to git as they are part of the package's public API and need to be tracked for proper version management.

scripts/generate-checksums.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#!/usr/bin/env node
2+
3+
import { createHash } from 'node:crypto'
4+
import { readFileSync, writeFileSync, readdirSync, statSync } from 'node:fs'
5+
import { join, relative } from 'node:path'
6+
import { fileURLToPath } from 'node:url'
7+
8+
const __dirname = fileURLToPath(new URL('.', import.meta.url))
9+
10+
/**
11+
* Recursively gets all files in a directory
12+
* @param {string} dir - Directory to scan
13+
* @param {string[]} fileList - Accumulator for file paths
14+
* @returns {string[]} Array of file paths
15+
*/
16+
function getAllFiles(dir, fileList = []) {
17+
try {
18+
const files = readdirSync(dir)
19+
20+
files.forEach((file) => {
21+
const filePath = join(dir, file)
22+
try {
23+
const stat = statSync(filePath)
24+
25+
if (stat.isDirectory()) {
26+
// Skip node_modules and dist directories
27+
if (file !== 'node_modules' && file !== 'dist') {
28+
getAllFiles(filePath, fileList)
29+
}
30+
} else {
31+
fileList.push(filePath)
32+
}
33+
} catch (err) {
34+
console.warn(`Warning: Could not read ${filePath}: ${err.message}`)
35+
}
36+
})
37+
} catch (err) {
38+
console.warn(`Warning: Could not read directory ${dir}: ${err.message}`)
39+
}
40+
41+
return fileList
42+
}
43+
44+
/**
45+
* Generates a checksum for all files in specified directories
46+
* @param {string} baseDir - Base directory path
47+
* @param {string[]} directories - Array of directory names to checksum
48+
* @returns {string} Hex checksum
49+
*/
50+
function generateChecksum(baseDir, directories) {
51+
const hash = createHash('sha256')
52+
const allFiles = []
53+
54+
// Collect all files from specified directories
55+
directories.forEach((dir) => {
56+
const dirPath = join(baseDir, dir)
57+
const files = getAllFiles(dirPath)
58+
allFiles.push(...files)
59+
})
60+
61+
// Sort files to ensure consistent ordering
62+
allFiles.sort()
63+
64+
// Hash each file's content
65+
allFiles.forEach((filePath) => {
66+
try {
67+
const content = readFileSync(filePath)
68+
const relativePath = relative(baseDir, filePath)
69+
// Include the file path in the hash for uniqueness
70+
hash.update(relativePath)
71+
hash.update(content)
72+
} catch (err) {
73+
console.warn(`Warning: Could not read ${filePath}: ${err.message}`)
74+
}
75+
})
76+
77+
return hash.digest('hex')
78+
}
79+
80+
/**
81+
* Generates checksum.ts file for a framework
82+
* @param {string} frameworkPath - Path to the framework directory
83+
* @param {string} frameworkName - Name of the framework for logging
84+
*/
85+
function generateChecksumFile(frameworkPath, frameworkName) {
86+
const directories = ['add-ons', 'examples', 'hosts', 'project', 'toolchains']
87+
const checksum = generateChecksum(frameworkPath, directories)
88+
89+
const checksumContent = `// This file is auto-generated. Do not edit manually.
90+
// Generated from add-ons, examples, hosts, project, and toolchains directories
91+
export const contentChecksum = '${checksum}'
92+
`
93+
94+
const checksumPath = join(frameworkPath, 'src', 'checksum.ts')
95+
writeFileSync(checksumPath, checksumContent, 'utf8')
96+
97+
console.log(`✓ Generated checksum for ${frameworkName}: ${checksum}`)
98+
}
99+
100+
// Main execution
101+
const rootDir = join(__dirname, '..')
102+
const reactCraPath = join(rootDir, 'frameworks', 'react-cra')
103+
const solidPath = join(rootDir, 'frameworks', 'solid')
104+
105+
console.log('Generating checksums...')
106+
generateChecksumFile(reactCraPath, 'react-cra')
107+
generateChecksumFile(solidPath, 'solid')
108+
console.log('✓ Checksums generated successfully')

0 commit comments

Comments
 (0)