@alessiofrittoli/package-configs 1.8.0-alpha.6 → 1.8.0-alpha.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alessiofrittoli/package-configs",
3
- "version": "1.8.0-alpha.6",
3
+ "version": "1.8.0-alpha.7",
4
4
  "description": "Utility library that offers base configurations for your packages.",
5
5
  "type": "module",
6
6
  "author": {
@@ -40,7 +40,7 @@
40
40
  "types": "./dist/index.d.mts",
41
41
  "files": [
42
42
  "dist",
43
- "scripts/install-dependencies.cjs"
43
+ "scripts/postinstall"
44
44
  ],
45
45
  "exports": {
46
46
  ".": {
@@ -0,0 +1,75 @@
1
+ const { default: installDependencies } = require('./install-dependencies.cjs')
2
+ const { Chain } = require('@alessiofrittoli/chain-functions')
3
+ const project = require('../../package.json')
4
+ const { readFileSync } = require('fs')
5
+ const path = require('path')
6
+
7
+ /**
8
+ * Reads and parses the `package.json` file from the specified root directory.
9
+ *
10
+ * @param {string} root The root directory where the `package.json` file is located.
11
+ *
12
+ * @throws Will throw an error if the file cannot be read or parsed.
13
+ *
14
+ * @returns {Record<string, string | Record<string, string>> & { name: string }} The parsed contents of the `package.json` file as an object.
15
+ */
16
+ const getPackageJson = root => JSON.parse(readFileSync(path.resolve(root, 'package.json')).toString())
17
+
18
+ /**
19
+ * Determines if the script is running in an external project.
20
+ *
21
+ * @param {{ root: string; name: string }} project - The options object excluding the 'outputFile' property.
22
+ * @returns {boolean} A boolean indicating whether the script is running in an external project.
23
+ * @throws Will throw an error if `INIT_CWD` is not set or if the script cannot determine the project status.
24
+ */
25
+ const isExternalPackage = ({ root, name }) => {
26
+ try {
27
+ const project = getPackageJson(root)
28
+
29
+ if (project.name.endsWith(name)) {
30
+ return false
31
+ }
32
+ return true
33
+ } catch (cause) {
34
+ throw new Error("Couldn't check if script is running in an external project.", { cause })
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Retrieves the root directory of the current process.
40
+ *
41
+ * @returns {string} The root directory of the current process, determined by the `INIT_CWD` environment variable if set,
42
+ * otherwise the current working directory.
43
+ */
44
+ const getProcessRoot = () => process.env.INIT_CWD || process.cwd()
45
+
46
+ // export type PostInstallChainFn = () => void | Promise<void>
47
+
48
+ /**
49
+ * @type import('@alessiofrittoli/chain-functions/types').LastChainLink<() => void | Promise<void>>
50
+ */
51
+ const lastChainLink = () => () => {
52
+ console.log({
53
+ package: project.name,
54
+ message: `Post-Install done. Thank you for installing ${project.name}!`,
55
+ })
56
+ }
57
+
58
+ /**
59
+ * @type import('@alessiofrittoli/chain-functions/types').ChainFactory<( { cwd }: { cwd: string } ) => void | Promise<void>>
60
+ */
61
+ const postInstallChain = [installDependencies, lastChainLink]
62
+
63
+ const runChain = async () => {
64
+ const cwd = getProcessRoot()
65
+
66
+ if (!isExternalPackage({ name: project.name, root: cwd })) {
67
+ return process.exit(0)
68
+ }
69
+
70
+ await Chain.functions(postInstallChain)({ cwd })
71
+
72
+ process.exit(0)
73
+ }
74
+
75
+ runChain().catch(console.error)
@@ -0,0 +1,179 @@
1
+ const { ReadStream, WriteStream } = require('tty')
2
+ const { execSync } = require('child_process')
3
+ const prompts = require('prompts')
4
+ const { openSync } = require('fs')
5
+
6
+ // // example writing user input data to stdout
7
+
8
+ // // const { openSync } = require('fs')
9
+ // // const { ReadStream, WriteStream } = require('tty')
10
+ // // const inputPath = process.platform === 'win32' ? 'CONIN$' : '/dev/tty'
11
+ // // const outputPath = process.platform === 'win32' ? 'CONOUT$' : '/dev/tty'
12
+
13
+ // // const stdin = new ReadStream(openSync(inputPath, 'r'))
14
+ // // const stdout = new WriteStream(openSync(outputPath, 'w'))
15
+ // const stdin = process.stdin
16
+ // const stdout = process.stdout
17
+
18
+ // stdin.setRawMode(true)
19
+ // stdin.resume()
20
+
21
+ // stdin.on( 'data', (data) => {
22
+ // stdout.write( data.toString() )
23
+
24
+ // if (data.includes('\x03')) {
25
+ // stdin.setRawMode(false)
26
+ // process.exit(0)
27
+ // }
28
+ // } )
29
+
30
+ /**
31
+ * Check whether script is running in a CI environment.
32
+ *
33
+ * @remarks Check if `CI` or `GITHUB_ACTIONS` is `true` or `GITHUB_WORKFLOW` is defined.
34
+ *
35
+ * @returns `true` if the script is running in a CI environment, `false` otherwise.
36
+ */
37
+ const isCIEnv = () =>
38
+ process.env.CI === 'true' ||
39
+ process.env.GITHUB_ACTIONS === 'true' ||
40
+ typeof process.env.GITHUB_WORKFLOW !== 'undefined'
41
+
42
+ /**
43
+ * Removes duplicate values from an array.
44
+ *
45
+ * @param array The input array.
46
+ * @returns The filtered array.
47
+ */
48
+ const arrayUnique = array => (array.length <= 0 ? array : [...new Set(array)])
49
+
50
+ /**
51
+ * @type import('@alessiofrittoli/chain-functions/types').ChainLink<( { cwd }: { cwd: string } ) => void | Promise<void>>
52
+ */
53
+ const installDependencies = next => async params => {
54
+ if (isCIEnv()) {
55
+ return next(params)
56
+ }
57
+
58
+ const { cwd } = params
59
+
60
+ try {
61
+ const inputPath = process.platform === 'win32' ? 'CONIN$' : '/dev/tty'
62
+ const outputPath = process.platform === 'win32' ? 'CONOUT$' : '/dev/tty'
63
+ const stdin = !process.stdin.isTTY ? new ReadStream(openSync(inputPath, 'r')) : undefined
64
+ const stdout = !process.stdin.isTTY ? new WriteStream(openSync(outputPath, 'w')) : undefined
65
+
66
+ const { installDeps } = await prompts([
67
+ {
68
+ type: 'confirm',
69
+ name: 'installDeps',
70
+ message: 'Would you like to install optional dependencies?',
71
+ initial: true,
72
+ stdin,
73
+ stdout,
74
+ },
75
+ ])
76
+
77
+ if (!installDeps) {
78
+ return next(params)
79
+ }
80
+
81
+ const { _dependenciesChoice } = await prompts([
82
+ {
83
+ type: 'multiselect',
84
+ name: '_dependenciesChoice',
85
+ message: "Please, select which tool you're going to use",
86
+ stdin,
87
+ stdout,
88
+ choices: [
89
+ {
90
+ title: 'Vite',
91
+ selected: true,
92
+ description: 'Will install Vite',
93
+ value: ['vite'],
94
+ },
95
+ {
96
+ title: 'Vitest',
97
+ selected: true,
98
+ description: 'Will install Vitest',
99
+ value: ['vitest', '@vitest/coverage-v8'],
100
+ },
101
+ {
102
+ title: 'Oxlint',
103
+ selected: true,
104
+ description: 'Will install Oxlint',
105
+ value: ['oxlint', 'oxlint-tsgolint'],
106
+ },
107
+ {
108
+ title: 'Prettier',
109
+ selected: true,
110
+ description: 'Will install Prettier',
111
+ value: ['prettier', 'prettier-plugin-sort-imports'],
112
+ },
113
+ {
114
+ title: 'tsdown',
115
+ selected: true,
116
+ description: 'Will install tsdown',
117
+ value: ['tsdown'],
118
+ },
119
+ {
120
+ title: 'ESLint',
121
+ selected: false,
122
+ description: 'Will install ESLint dev dependencies',
123
+ value: [
124
+ 'eslint',
125
+ '@eslint/compat',
126
+ '@eslint/eslintrc',
127
+ '@eslint/js',
128
+ 'globals',
129
+ 'typescript-eslint',
130
+ ],
131
+ },
132
+ {
133
+ title: 'Next.js',
134
+ description: 'Will install Next.js related ESLint dev dependencies',
135
+ selected: false,
136
+ value: [
137
+ 'eslint',
138
+ '@eslint/compat',
139
+ '@eslint/eslintrc',
140
+ '@eslint/js',
141
+ 'globals',
142
+ 'typescript-eslint',
143
+ ],
144
+ },
145
+ ],
146
+ },
147
+ ])
148
+
149
+ if (!_dependenciesChoice) {
150
+ return next(params)
151
+ }
152
+
153
+ const dependenciesChoice = arrayUnique(_dependenciesChoice.flatMap(choice => choice))
154
+
155
+ if (dependenciesChoice.length <= 0) {
156
+ return next(params)
157
+ }
158
+
159
+ let engine = 'npm'
160
+
161
+ try {
162
+ execSync('pnpm -v', { cwd, stdio: 'ignore' })
163
+ engine = 'pnpm'
164
+ } catch {
165
+ engine = 'npm'
166
+ }
167
+
168
+ const installCommand = engine === 'npm' ? 'npm install --save-dev' : 'pnpm add --save-dev'
169
+
170
+ // execSync(`${installCommand} ${dependenciesChoice.join(' ')}`, { cwd, stdio: 'inherit' })
171
+ execSync(`${installCommand} ${dependenciesChoice.join(' ')}`, { cwd, stdio: 'ignore' })
172
+
173
+ return next(params)
174
+ } catch {
175
+ return next(params)
176
+ }
177
+ }
178
+
179
+ module.exports = installDependencies
@@ -1,186 +0,0 @@
1
- const { execSync } = require('child_process')
2
- const prompts = require('prompts')
3
-
4
- // // example writing user input data to stdout
5
-
6
- // // const { openSync } = require('fs')
7
- // // const { ReadStream, WriteStream } = require('tty')
8
- // // const inputPath = process.platform === 'win32' ? 'CONIN$' : '/dev/tty'
9
- // // const outputPath = process.platform === 'win32' ? 'CONOUT$' : '/dev/tty'
10
-
11
- // // const stdin = new ReadStream(openSync(inputPath, 'r'))
12
- // // const stdout = new WriteStream(openSync(outputPath, 'w'))
13
- // const stdin = process.stdin
14
- // const stdout = process.stdout
15
-
16
- // stdin.setRawMode(true)
17
- // stdin.resume()
18
-
19
- // stdin.on( 'data', (data) => {
20
- // stdout.write( data.toString() )
21
-
22
- // if (data.includes('\x03')) {
23
- // stdin.setRawMode(false)
24
- // process.exit(0)
25
- // }
26
- // } )
27
-
28
- /**
29
- * Check whether script is running in a CI environment.
30
- *
31
- * @remarks Check if `CI` or `GITHUB_ACTIONS` is `true` or `GITHUB_WORKFLOW` is defined.
32
- *
33
- * @returns `true` if the script is running in a CI environment, `false` otherwise.
34
- */
35
- const isCIEnv = () =>
36
- process.env.CI === 'true' ||
37
- process.env.GITHUB_ACTIONS === 'true' ||
38
- typeof process.env.GITHUB_WORKFLOW !== 'undefined'
39
-
40
- /**
41
- * Removes duplicate values from an array.
42
- *
43
- * @param array The input array.
44
- * @returns The filtered array.
45
- */
46
- const arrayUnique = array => (array.length <= 0 ? array : [...new Set(array)])
47
-
48
- /**
49
- * Retrieves the root directory of the current process.
50
- *
51
- * @returns The root directory of the current process, determined by the `INIT_CWD` environment variable if set,
52
- * otherwise the current working directory.
53
- */
54
- const getProcessRoot = () => process.env.INIT_CWD || process.cwd()
55
-
56
- const installDependencies = async () => {
57
- if (isCIEnv()) {
58
- return process.exit(0)
59
- }
60
-
61
- const cwd = getProcessRoot()
62
-
63
- try {
64
- const { installDeps } = await prompts(
65
- [
66
- {
67
- type: 'confirm',
68
- name: 'installDeps',
69
- message: 'Would you like to install optional dependencies?',
70
- initial: true,
71
- },
72
- ],
73
- {
74
- onCancel() {
75
- process.exit(0)
76
- },
77
- },
78
- )
79
-
80
- if (!installDeps) {
81
- return process.exit(0)
82
- }
83
-
84
- const { _dependenciesChoice } = await prompts(
85
- [
86
- {
87
- type: 'multiselect',
88
- name: '_dependenciesChoice',
89
- message: "Please, select which tool you're going to use",
90
- choices: [
91
- {
92
- title: 'Vite',
93
- selected: true,
94
- description: 'Will install Vite',
95
- value: ['vite'],
96
- },
97
- {
98
- title: 'Vitest',
99
- selected: true,
100
- description: 'Will install Vitest',
101
- value: ['vitest', '@vitest/coverage-v8'],
102
- },
103
- {
104
- title: 'Oxlint',
105
- selected: true,
106
- description: 'Will install Oxlint',
107
- value: ['oxlint', 'oxlint-tsgolint'],
108
- },
109
- {
110
- title: 'Prettier',
111
- selected: true,
112
- description: 'Will install Prettier',
113
- value: ['prettier', 'prettier-plugin-sort-imports'],
114
- },
115
- {
116
- title: 'tsdown',
117
- selected: true,
118
- description: 'Will install tsdown',
119
- value: ['tsdown'],
120
- },
121
- {
122
- title: 'ESLint',
123
- selected: false,
124
- description: 'Will install ESLint dev dependencies',
125
- value: [
126
- 'eslint',
127
- '@eslint/compat',
128
- '@eslint/eslintrc',
129
- '@eslint/js',
130
- 'globals',
131
- 'typescript-eslint',
132
- ],
133
- },
134
- {
135
- title: 'Next.js',
136
- description: 'Will install Next.js related ESLint dev dependencies',
137
- selected: false,
138
- value: [
139
- 'eslint',
140
- '@eslint/compat',
141
- '@eslint/eslintrc',
142
- '@eslint/js',
143
- 'globals',
144
- 'typescript-eslint',
145
- ],
146
- },
147
- ],
148
- },
149
- ],
150
- {
151
- onCancel() {
152
- process.exit(0)
153
- },
154
- },
155
- )
156
-
157
- if (!_dependenciesChoice) {
158
- return process.exit(0)
159
- }
160
-
161
- const dependenciesChoice = arrayUnique(_dependenciesChoice.flatMap(choice => choice))
162
-
163
- if (dependenciesChoice.length <= 0) {
164
- return process.exit(0)
165
- }
166
-
167
- let engine = 'npm'
168
-
169
- try {
170
- execSync('pnpm -v', { cwd, stdio: 'ignore' })
171
- engine = 'pnpm'
172
- } catch {
173
- engine = 'npm'
174
- }
175
-
176
- const installCommand = engine === 'npm' ? 'npm install --save-dev' : 'pnpm add --save-dev'
177
-
178
- execSync(`${installCommand} ${dependenciesChoice.join(' ')}`, { cwd, stdio: 'inherit' })
179
-
180
- process.exit(0)
181
- } catch {
182
- return process.exit(0)
183
- }
184
- }
185
-
186
- installDependencies().catch(console.error)