sqlx-ts 0.31.0 → 0.34.0

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/.eslintrc.js CHANGED
@@ -1,6 +1,7 @@
1
1
  module.exports = {
2
2
  "env": {
3
- "browser": true,
3
+ "browser": false,
4
+ "node": true,
4
5
  "es2021": true,
5
6
  },
6
7
  "extends": [
@@ -15,5 +16,7 @@ module.exports = {
15
16
  "plugins": [
16
17
  "@typescript-eslint",
17
18
  ],
18
- "rules": {},
19
+ "rules": {
20
+ "@typescript-eslint/no-var-requires": "off"
21
+ },
19
22
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sqlx-ts",
3
- "version": "0.31.0",
3
+ "version": "0.34.0",
4
4
  "description": "sqlx-ts ensures your raw SQLs are compile-time checked",
5
5
  "main": "dist/index.js",
6
6
  "maintainers": [
@@ -17,6 +17,9 @@
17
17
  "test": "npx jest",
18
18
  "prepublishOnly": "cp ../README.md . && npm i && npm run compile"
19
19
  },
20
+ "dependencies": {
21
+ "adm-zip": "^0.5.16"
22
+ },
20
23
  "devDependencies": {
21
24
  "@types/jest": "^27.4.1",
22
25
  "@types/node": "^20.14.8",
package/postinstall.js CHANGED
@@ -1,8 +1,194 @@
1
- let execSync = require('child_process').execSync
2
- let tag = require('./package.json').version
1
+ const { createHash } = require('crypto')
2
+ const fs = require('fs')
3
+ const https = require('https')
4
+ const path = require('path')
5
+ const os = require('os')
6
+ const tag = require('./package.json').version
7
+ const AdmZip = require('adm-zip')
3
8
 
4
- const os = process.platform
9
+ const platform = process.platform
5
10
  const cpu = process.arch
6
11
 
7
- execSync(`curl -LSfs https://jasonshin.github.io/sqlx-ts/install.sh | sh -s -- --os ${os} --cpu ${cpu} --tag ${tag} -f`, { stdio: 'inherit' })
8
- console.info('sqlx-ts installation successful')
12
+ const colors = {
13
+ reset: "\x1b[0m",
14
+ red: "\x1b[31m",
15
+ green: "\x1b[32m",
16
+ yellow: "\x1b[33m",
17
+ cyan: "\x1b[36m",
18
+ }
19
+
20
+ const info = (msg) => console.log(`${colors.cyan}INFO: ${msg} ${colors.reset}`)
21
+ const success = (msg) => console.log(`${colors.green}SUCCESS: ${msg} ${colors.reset}`)
22
+ const warn = (msg) => console.warn(`${colors.yellow}WARNING: ${msg} ${colors.reset}`)
23
+ const error = (msg) => console.error(`${colors.red}ERROR: ${msg} ${colors.reset}`)
24
+
25
+ function getBinaryInfo() {
26
+ let build = ''
27
+ if (platform === 'darwin') {
28
+ if (cpu === 'arm64') {
29
+ build = 'macos-arm'
30
+ } else {
31
+ build = 'macos-64-bit'
32
+ }
33
+ } else if (platform === 'win32') {
34
+ if (cpu === 'x64') {
35
+ build = 'windows-64-bit'
36
+ } else {
37
+ build = 'windows-32-bit'
38
+ }
39
+ } else if (platform === 'linux') {
40
+ if (cpu === 'x64') {
41
+ build = 'linux-64-bit'
42
+ } else if (cpu === 'arm64') {
43
+ build = 'linux-arm'
44
+ } else {
45
+ build = 'linux-32-bit'
46
+ }
47
+ } else {
48
+ throw new Error(`Unsupported platform: ${platform}-${cpu}`)
49
+ }
50
+
51
+ return {
52
+ build,
53
+ filename: `sqlx-ts-v${tag}-${build}.zip`,
54
+ binaryName: platform === 'win32' ? 'sqlx-ts.exe' : 'sqlx-ts'
55
+ }
56
+ }
57
+
58
+ function safeUnlink(filePath) {
59
+ try {
60
+ if (fs.existsSync(filePath)) {
61
+ fs.unlinkSync(filePath)
62
+ }
63
+ } catch (err) {
64
+ warn(`Failed to delete file: filePath: ${filePath}, err: ${err.message}`)
65
+ }
66
+ }
67
+
68
+ // Download file from URL
69
+ function downloadFile(url, destination, redirectCount = 0) {
70
+ return new Promise((resolve, reject) => {
71
+ if (redirectCount > 5) {
72
+ return reject(new Error("Too many redirects while downloading file"))
73
+ }
74
+
75
+ const file = fs.createWriteStream(destination)
76
+ https.get(url, (response) => {
77
+ if (response.statusCode === 302 || response.statusCode === 301) {
78
+ // Handle redirects
79
+ // Close the current file and delete it
80
+ // Then download from the new location
81
+ file.close()
82
+ safeUnlink(destination)
83
+ return downloadFile(response.headers.location, destination, redirectCount + 1)
84
+ .then(resolve)
85
+ .catch(reject)
86
+ }
87
+
88
+ if (response.statusCode !== 200) {
89
+ file.close()
90
+ safeUnlink(destination)
91
+ return reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`))
92
+ }
93
+
94
+ response.pipe(file)
95
+ file.on('finish', () => {
96
+ file.close(resolve)
97
+ })
98
+ }).on('error', (err) => {
99
+ safeUnlink(destination)
100
+ reject(err)
101
+ })
102
+ })
103
+ }
104
+
105
+ // Calculate SHA-256 hash of a file
106
+ function calculateSHA256(filePath) {
107
+ return new Promise((resolve, reject) => {
108
+ const hash = createHash('sha256')
109
+ const stream = fs.createReadStream(filePath)
110
+
111
+ stream.on('data', (data) => hash.update(data))
112
+ stream.on('end', () => resolve(hash.digest('hex')))
113
+ stream.on('error', reject)
114
+ })
115
+ }
116
+
117
+ async function verifyHash(filePath, expectedHash) {
118
+ const actualHash = await calculateSHA256(filePath)
119
+
120
+ if (actualHash !== expectedHash) {
121
+ throw new Error(
122
+ `Hash mismatch!\n` +
123
+ `Expected: ${expectedHash}\n` +
124
+ `Got: ${actualHash}\n` +
125
+ `This could indicate a corrupted download or a security issue.`
126
+ )
127
+ }
128
+
129
+ return true
130
+ }
131
+
132
+ function extractBinary(zipPath, binaryName, targetPath) {
133
+ const zip = new AdmZip(zipPath)
134
+ const zipEntries = zip.getEntries()
135
+
136
+ for (const entry of zipEntries) {
137
+ if (entry.entryName.endsWith(binaryName)) {
138
+ // Extract the entry's content directly
139
+ const data = entry.getData()
140
+ fs.writeFileSync(targetPath, data)
141
+ fs.chmodSync(targetPath, 0o755)
142
+ return
143
+ }
144
+ }
145
+
146
+ throw new Error(`Binary ${binaryName} not found in archive`)
147
+ }
148
+
149
+ async function install() {
150
+ try {
151
+ const { filename, binaryName } = getBinaryInfo()
152
+ const baseUrl = `https://github.com/JasonShin/sqlx-ts/releases/download/v${tag}`
153
+ const zipUrl = `${baseUrl}/${filename}`
154
+ const checksumUrl = `${zipUrl}.sha256`
155
+
156
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'sqlx-ts-'))
157
+ const zipPath = path.join(tmpDir, filename)
158
+ const checksumPath = path.join(tmpDir, `${filename}.sha256`)
159
+ const targetPath = path.join(__dirname, 'sqlx-ts' + (platform === 'win32' ? '.exe' : ''))
160
+
161
+ info(`Downloading sqlx-ts v${tag} for ${platform}-${cpu}...`)
162
+ info(`URL: ${zipUrl}`)
163
+
164
+ // Download the zip file
165
+ await downloadFile(zipUrl, zipPath)
166
+ success('Download complete')
167
+
168
+ // Download and verify the checksum
169
+ info('Downloading checksum...')
170
+ await downloadFile(checksumUrl, checksumPath)
171
+ const expectedHash = fs.readFileSync(checksumPath, 'utf8').trim()
172
+ info(`Expected SHA-256: ${expectedHash}`)
173
+
174
+ // Verify the hash
175
+ info('Verifying checksum...')
176
+ await verifyHash(zipPath, expectedHash)
177
+ success('Checksum verified successfully')
178
+
179
+ // Extract the binary
180
+ info('Extracting binary...')
181
+ extractBinary(zipPath, binaryName, targetPath)
182
+
183
+ // Cleanup
184
+ fs.rmSync(tmpDir, { recursive: true, force: true })
185
+
186
+ info('sqlx-ts installation successful')
187
+ process.exit(0)
188
+ } catch (err) {
189
+ error(`Installation failed: ${err.message}`)
190
+ process.exit(1)
191
+ }
192
+ }
193
+
194
+ install()
package/sqlx-ts CHANGED
Binary file
@@ -1,10 +0,0 @@
1
- // This script is executed as part of sqlx-ts CI pipeline to test local ../scripts/install.sh changes
2
- // DO NOT USE THIS IN PRODUCTION
3
- let execSync = require('child_process').execSync
4
- let tag = require('./package.json').version
5
-
6
- const os = process.platform
7
- const cpu = process.arch
8
-
9
- execSync(`sh ../scripts/install.sh -s -- --os ${os} --cpu ${cpu} --tag ${tag} -f`, { stdio: 'inherit' })
10
- console.info('sqlx-ts installation successful')