@citruslime/create-boilerplate 1.6.0-beta.0 → 2.0.0-beta.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Citrus-Lime UI Library Create Boilerplate Script
2
2
 
3
- A create package script for initialising new Citrus-Lime web apps.
3
+ A create package script for initialising new apps with the Citrus-Lime default configuration.
4
4
 
5
5
  ![version](https://img.shields.io/npm/v/@citruslime/create-boilerplate/latest)
6
6
  ![version next](https://img.shields.io/npm/v/@citruslime/create-boilerplate/next)
@@ -10,7 +10,7 @@ A create package script for initialising new Citrus-Lime web apps.
10
10
  - 📌 [Citrus-Lime Ltd](https://www.citruslime.com)
11
11
 
12
12
 
13
- `npm init @citruslime/boilerplate TargetDirectory`
13
+ `pnpm create @citruslime/boilerplate TargetDirectory`
14
14
 
15
15
  or
16
16
 
@@ -18,7 +18,7 @@ or
18
18
 
19
19
  or
20
20
 
21
- `pnpm create @citruslime/boilerplate TargetDirectory`
21
+ `npm init @citruslime/boilerplate TargetDirectory`
22
22
 
23
23
  - **TargetDirectory**
24
24
  - A relative folder path for the script to create the boilerplate app
@@ -26,4 +26,4 @@ or
26
26
 
27
27
  e.g.
28
28
 
29
- `yarn create @citruslime/boilerplate ./ui/customer`
29
+ `pnpm create @citruslime/boilerplate ./ui/customer`
@@ -1,11 +1,8 @@
1
1
  #!/bin/sh
2
2
  . "$(dirname "$0")/_/husky.sh"
3
- . "$(dirname "$0")/common.sh"
4
3
 
5
- yarn_directory="$APPDATA\npm\node_modules\yarn\bin"
6
-
7
- if ! command -v "$yarn_directory\yarn" -v; then
8
- npm install --global yarn
4
+ if ! command -v pnpm; then
5
+ choco install pnpm -y
9
6
  fi
10
7
 
11
- "$yarn_directory\yarn" install --cwd "[[PACKAGE_DIR]]"
8
+ pnpm install -w -C "[[PACKAGE_DIR]]"
package/hooks/post-merge CHANGED
@@ -1,11 +1,8 @@
1
1
  #!/bin/sh
2
2
  . "$(dirname "$0")/_/husky.sh"
3
- . "$(dirname "$0")/common.sh"
4
3
 
5
- yarn_directory="$APPDATA\npm\node_modules\yarn\bin"
6
-
7
- if ! command -v "$yarn_directory\yarn" -v; then
8
- npm install --global yarn
4
+ if ! command -v pnpm; then
5
+ choco install pnpm -y
9
6
  fi
10
7
 
11
- "$yarn_directory\yarn" install --cwd "[[PACKAGE_DIR]]"
8
+ pnpm install -w -C "[[PACKAGE_DIR]]"
package/hooks/pre-commit CHANGED
@@ -1,11 +1,8 @@
1
1
  #!/bin/sh
2
2
  . "$(dirname "$0")/_/husky.sh"
3
- . "$(dirname "$0")/common.sh"
4
3
 
5
- yarn_directory="$APPDATA\npm\node_modules\yarn\bin"
6
-
7
- if ! command -v "$yarn_directory\yarn" -v; then
8
- npm install --global yarn
4
+ if ! command -v pnpm; then
5
+ choco install pnpm -y
9
6
  fi
10
7
 
11
- "$yarn_directory\yarn" --cwd "[[PACKAGE_DIR]]" pre-commit-lint
8
+ pnpm -C "[[PACKAGE_DIR]]" pre-commit-lint
@@ -1,11 +1,10 @@
1
1
  #!/usr/bin/env node
2
-
3
2
  import { execSync } from 'node:child_process';
4
3
  import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
5
4
  import { join, relative } from 'node:path';
6
5
  import { fileURLToPath, URL } from 'node:url';
7
6
 
8
- import { green, lightBlue, lightYellow, red } from 'kolorist';
7
+ import { green, lightBlue, red } from 'kolorist';
9
8
  import parseArgs from 'minimist';
10
9
  import prompts from 'prompts';
11
10
 
@@ -29,12 +28,11 @@ const filesToRename = {
29
28
  _gitattributes: '.gitattributes',
30
29
  _gitignore: '.gitignore',
31
30
  _editorconfig: '.editorconfig',
32
- _eslintignore: '.eslintignore',
33
- '_eslintrc.cjs': '.eslintrc.cjs',
34
- '_lintstagedrc.json': '.lintstagedrc.json',
31
+ '_lintstagedrc.js': '.lintstagedrc.js',
35
32
  _stylelintignore: '.stylelintignore',
36
- '_stylelintrc.cjs': '.stylelintrc.cjs',
37
- 'template.code-workspace': 'citrus-lime.code-workspace'
33
+ '_stylelint.config.js': 'stylelint.config.js',
34
+ 'template.code-workspace': 'citrus-lime.code-workspace',
35
+ _npmrc: '.npmrc'
38
36
  /* eslint-enable @typescript-eslint/naming-convention */
39
37
  };
40
38
 
@@ -69,7 +67,7 @@ const dependenciesToInstall = [
69
67
  dev: true
70
68
  },
71
69
  {
72
- name: '@tsconfig/node18',
70
+ name: '@tsconfig/node20',
73
71
  dev: true
74
72
  },
75
73
  {
@@ -153,17 +151,17 @@ async function init () {
153
151
  type: 'text',
154
152
  name: 'packageName',
155
153
  message: 'Enter a name for the project:',
156
- validate: (value) => /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(value) || 'Invalid package name'
154
+ validate: value => /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(value) || 'Invalid package name'
157
155
  },
158
156
  {
159
157
  type: packageDir ? null : 'text',
160
158
  name: 'packageDir',
161
159
  message: 'Enter a directory for the project:',
162
160
  initial: '.',
163
- onState: (state) => packageDir = state.value
161
+ onState: state => packageDir = state.value
164
162
  },
165
163
  {
166
- type: () => !existsSync(packageDir) || readdirSync(packageDir).length === 0 ? null : 'confirm',
164
+ type: () => directoryValid(packageDir) ? null : 'confirm',
167
165
  name: 'empty',
168
166
  message: () => `${packageDir === '.' ? 'Current directory' : `Target directory "${packageDir}"`} is not empty. Remove existing files and continue?`
169
167
  },
@@ -184,7 +182,7 @@ async function init () {
184
182
  initial: true
185
183
  },
186
184
  {
187
- type: (prev) => prev ? 'text' : null,
185
+ type: prev => prev ? 'text' : null,
188
186
  name: 'backendPort',
189
187
  message: 'Enter the port that the backend server runs on:',
190
188
  initial: 0
@@ -194,14 +192,14 @@ async function init () {
194
192
  name: 'packageManager',
195
193
  message: 'Select a package manager:',
196
194
  choices: [
197
- {
198
- title: 'yarn',
199
- value: 'yarn'
200
- },
201
195
  {
202
196
  title: 'pnpm',
203
197
  value: 'pnpm'
204
198
  },
199
+ {
200
+ title: 'yarn',
201
+ value: 'yarn'
202
+ },
205
203
  {
206
204
  title: 'npm',
207
205
  value: 'npm'
@@ -217,7 +215,7 @@ async function init () {
217
215
 
218
216
  packageDir = packageDir.toString();
219
217
 
220
- setReplacements(packageName, packageDir, rootDir, backendPort ?? 0);
218
+ setReplacements(packageName, packageDir, rootDir, backendPort ?? 0, packageManager);
221
219
  prepareDir(join(cwd, packageDir), empty);
222
220
  copyTemplate(packageDir);
223
221
 
@@ -230,6 +228,22 @@ async function init () {
230
228
  print(green(`Package ${packageName} has been successfully initialised in ${packageDir}.`), true);
231
229
  }
232
230
 
231
+ /**
232
+ * Checks if a directory is valid for project creation.
233
+ *
234
+ * @param {string} packageDir The directory of the package being created.
235
+ * @returns True, if the directory is valid; false, otherwise.
236
+ */
237
+ function directoryValid (packageDir) {
238
+ const directoryExists = !existsSync(packageDir);
239
+ const directorySize = readdirSync(packageDir).length;
240
+ const directoryOnlyContainsGit = directorySize === 1 && existsSync(`${packageDir}/.git`);
241
+
242
+ return !directoryExists ||
243
+ directorySize === 0 ||
244
+ directoryOnlyContainsGit;
245
+ }
246
+
233
247
  /**
234
248
  * Set the dynamic values for the file renaming and placeholder replacements.
235
249
  *
@@ -237,8 +251,9 @@ async function init () {
237
251
  * @param {string} packageDir The directory of the package being created.
238
252
  * @param {string} rootDir The relative path of the root of the repository.
239
253
  * @param {number} backendPort The port that the backend server runs on.
254
+ * @param packageManager The selected package manager to use.
240
255
  */
241
- function setReplacements (packageName, packageDir, rootDir, backendPort) {
256
+ function setReplacements (packageName, packageDir, rootDir, backendPort, packageManager) {
242
257
  const husky = relative(join(cwd, packageDir, '.vscode'), join(rootDir, '.husky'));
243
258
  const repoRoot = relative(join(cwd, packageDir), rootDir);
244
259
  const projDir = relative(rootDir, join(cwd, packageDir));
@@ -249,6 +264,7 @@ function setReplacements (packageName, packageDir, rootDir, backendPort) {
249
264
  placeholdersToReplace['[[ROOT_DIR]]'] = repoRoot.replaceAll('\\', '/');
250
265
  placeholdersToReplace['[[HUSKY_DIR]]'] = husky.replaceAll('\\', '/');
251
266
  placeholdersToReplace['\'[[FRONTEND_PORT]]\''] = Math.floor(Math.random() * 1001) + 4000;
267
+ placeholdersToReplace['[[PACKAGE_MANAGER]]'] = packageManager;
252
268
 
253
269
  if (backendPort !== 0) {
254
270
  placeholdersToReplace['\'[[PROXY]]\''] = `{
@@ -276,7 +292,7 @@ function prepareDir (path, empty) {
276
292
 
277
293
  print(lightBlue('Emptying directory...'), true);
278
294
 
279
- forEachInDir(path, (item) => rmSync(join(path, item), options));
295
+ forEachInDir(path, item => rmSync(join(path, item), options));
280
296
  }
281
297
  else if (!existsSync(path)) {
282
298
  print(lightBlue('Creating directory...'), true);
@@ -293,7 +309,7 @@ function prepareDir (path, empty) {
293
309
  function copyTemplate (packageDir) {
294
310
  const templateDir = join(codeDir, 'template');
295
311
 
296
- forEachInDir(templateDir, (item) => copy(templateDir, packageDir, item));
312
+ forEachInDir(templateDir, item => copy(templateDir, packageDir, item));
297
313
  }
298
314
 
299
315
  /**
@@ -305,12 +321,7 @@ function copyHooks (rootDir) {
305
321
  const hooksDir = join(codeDir, 'hooks');
306
322
  const huskyDir = join(rootDir, '.husky');
307
323
 
308
- if (existsSync(join(huskyDir, 'common.sh'))) {
309
- print(lightYellow('Git Hooks already installed by another package in this repo. These will need to be edited manually.\n'), true);
310
- }
311
- else {
312
- forEachInDir(hooksDir, (item) => copy(hooksDir, huskyDir, item));
313
- }
324
+ forEachInDir(hooksDir, item => copy(hooksDir, huskyDir, item));
314
325
  }
315
326
 
316
327
  /**
@@ -329,7 +340,7 @@ function copy (source, destination, item) {
329
340
 
330
341
  mkdirSync(destinationDir, { recursive: true });
331
342
 
332
- forEachInDir(sourceItem, (item) => copy(sourceItem, destinationDir, item));
343
+ forEachInDir(sourceItem, item => copy(sourceItem, destinationDir, item));
333
344
  }
334
345
  else {
335
346
  const destinationFile = filesToRename[item] ? join(destination, filesToRename[item]) : join(destination, item);
@@ -369,19 +380,26 @@ function installDependencies (packageManager) {
369
380
  print(lightBlue('Installing dev dependencies...'), true);
370
381
 
371
382
  let devDependencies = '';
383
+
372
384
  for (const dependency of dependenciesToInstall.filter(d => d.dev)) {
373
385
  devDependencies += `${dependency.name}${dependency.next ? '@next' : '@latest'} `;
374
386
  }
375
387
 
388
+ execSync(`${prefix} -D ${devDependencies}`);
389
+
376
390
  print(lightBlue('Installing dependencies...'), true);
377
391
 
378
392
  let dependencies = '';
393
+
379
394
  for (const dependency of dependenciesToInstall.filter(d => !d.dev)) {
380
395
  dependencies += `${dependency.name}${dependency.next ? '@next' : '@latest'} `;
381
396
  }
382
397
 
383
- execSync(`${prefix} -D ${devDependencies}`);
384
398
  execSync(`${prefix} ${dependencies}`);
399
+
400
+ print(lightBlue('Running final install...'), true);
401
+
402
+ execSync(`${packageManager} install`);
385
403
  }
386
404
 
387
405
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@citruslime/create-boilerplate",
3
3
  "type": "module",
4
- "version": "1.6.0-beta.0",
4
+ "version": "2.0.0-beta.0",
5
5
  "author": {
6
6
  "name": "Citrus-Lime Ltd",
7
7
  "url": "https://citruslime.com"
@@ -12,19 +12,22 @@
12
12
  "access": "public"
13
13
  },
14
14
  "files": [
15
- "main.mjs",
15
+ "main.js",
16
16
  "template",
17
17
  "hooks"
18
18
  ],
19
19
  "maintainers": [
20
20
  "Citrus-Lime"
21
21
  ],
22
- "main": "main.mjs",
22
+ "main": "main.js",
23
23
  "bin": {
24
- "create-boilerplate": "main.mjs"
24
+ "create-boilerplate": "main.js"
25
25
  },
26
26
  "engines": {
27
- "node": ">=16.0.0"
27
+ "node": ">=18.0.0"
28
+ },
29
+ "scripts": {
30
+ "lint": "eslint . --fix && stylelint **/*.{css,vue} --fix"
28
31
  },
29
32
  "dependencies": {
30
33
  "kolorist": "^1.7.0",
@@ -6,13 +6,14 @@
6
6
  "editor.defaultFormatter": "vscode.json-language-features"
7
7
  },
8
8
  "editor.codeActionsOnSave": {
9
- "source.fixAll": true,
10
- "source.fixAll.eslint": true,
11
- "source.fixAll.stylelint": true,
12
- "source.organizeImports": false
9
+ "source.fixAll": "explicit",
10
+ "source.fixAll.eslint": "explicit",
11
+ "source.fixAll.stylelint": "explicit",
12
+ "source.organizeImports": "never"
13
13
  },
14
14
  "editor.defaultFormatter": "dbaeumer.vscode-eslint",
15
15
  "editor.formatOnSave": true,
16
+ "eslint.experimental.useFlatConfig": true,
16
17
  "eslint.validate": [
17
18
  "html",
18
19
  "javascript",
@@ -17,13 +17,14 @@
17
17
  "editor.defaultFormatter": "vscode.json-language-features"
18
18
  },
19
19
  "editor.codeActionsOnSave": {
20
- "source.fixAll": true,
21
- "source.fixAll.eslint": true,
22
- "source.fixAll.stylelint": true,
23
- "source.organizeImports": false
20
+ "source.fixAll": "explicit",
21
+ "source.fixAll.eslint": "explicit",
22
+ "source.fixAll.stylelint": "explicit",
23
+ "source.organizeImports": "never"
24
24
  },
25
25
  "editor.defaultFormatter": "dbaeumer.vscode-eslint",
26
26
  "editor.formatOnSave": true,
27
+ "eslint.experimental.useFlatConfig": true,
27
28
  "eslint.validate": [
28
29
  "html",
29
30
  "javascript",
@@ -0,0 +1,5 @@
1
+ /* eslint-disable @typescript-eslint/naming-convention */
2
+ export default {
3
+ './**/*.+(js|cjs|mjs|ts|cts|mts|vue)': ['eslint --fix'],
4
+ './**/*.(css|vue)': ['stylelint --fix']
5
+ };
@@ -0,0 +1,2 @@
1
+ public-hoist-pattern[]=*eslint*
2
+ public-hoist-pattern[]=*stylelint*
@@ -0,0 +1,5 @@
1
+ import config from '@citruslime/config/stylelint';
2
+
3
+ export default {
4
+ extends: [config]
5
+ };
@@ -0,0 +1,21 @@
1
+ import config from '@citruslime/config/eslint';
2
+ import { FlatCompat } from '@eslint/eslintrc';
3
+
4
+ const compat = new FlatCompat({
5
+ baseDirectory: import.meta.url
6
+ });
7
+
8
+ export default [
9
+ ...config,
10
+ ...compat.extends('./.eslintrc-auto-import.json'),
11
+ {
12
+ ignores: [
13
+ 'dist',
14
+ 'node_modules',
15
+ '**/*.html',
16
+ 'auto-imports.d.ts',
17
+ 'components.d.ts',
18
+ 'typed-router.d.ts'
19
+ ]
20
+ }
21
+ ];
@@ -9,8 +9,8 @@
9
9
  "build-only": "vite build",
10
10
  "type-check": "vue-tsc --noEmit",
11
11
  "serve": "vite preview",
12
- "lint": "eslint . --ext .js,.cjs,.mjs,.ts,.vue --fix && stylelint **/*.{css,vue} --fix",
13
- "pre-commit-lint": "yarn lint-staged",
14
- "prepare": "cd [[ROOT_DIR]] && husky install"
12
+ "lint": "eslint . --fix && stylelint **/*.{css,vue} --fix",
13
+ "pre-commit-lint": "[[PACKAGE_MANAGER]] lint-staged",
14
+ "prepare": "cd [[ROOT_DIR]] && husky"
15
15
  }
16
16
  }
@@ -14,8 +14,8 @@
14
14
  ],
15
15
  "compilerOptions": {
16
16
  "composite": true,
17
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
17
18
  "baseUrl": ".",
18
- "moduleResolution": "node",
19
19
  "lib": [
20
20
  "ESNext",
21
21
  "DOM",
@@ -25,6 +25,9 @@
25
25
  "@/*": [
26
26
  "./src/*"
27
27
  ]
28
- }
28
+ },
29
+ "types": [
30
+ "unplugin-vue-router/client"
31
+ ]
29
32
  }
30
33
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "@tsconfig/node18/tsconfig.json",
2
+ "extends": "@tsconfig/node20/tsconfig.json",
3
3
  "include": [
4
4
  "vite.config.*",
5
5
  "vitest.config.*",
@@ -7,8 +7,9 @@
7
7
  ],
8
8
  "compilerOptions": {
9
9
  "composite": true,
10
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
10
11
  "module": "ESNext",
11
- "moduleResolution": "node",
12
+ "moduleResolution": "Bundler",
12
13
  "types": [
13
14
  "node"
14
15
  ]
@@ -69,7 +69,12 @@ export default defineConfig({
69
69
  output: {
70
70
  manualChunks (id) {
71
71
  if (id.includes('node_modules')) {
72
- return id.toString().split('node_modules/')[1].split('/')[0].toString();
72
+ if (id.includes('.pnpm')) {
73
+ return id.toString().split('node_modules/.pnpm')[1].split('/')[1].toString();
74
+ }
75
+ else {
76
+ return id.toString().split('node_modules/')[1].split('/')[0].toString();
77
+ }
73
78
  }
74
79
  }
75
80
  }
@@ -95,7 +100,6 @@ export default defineConfig({
95
100
  },
96
101
  server: {
97
102
  open: true,
98
- https: true,
99
103
  port: '[[FRONTEND_PORT]]',
100
104
  proxy: '[[PROXY]]'
101
105
  }
package/hooks/common.sh DELETED
@@ -1,7 +0,0 @@
1
- command_exists () {
2
- command -v "$1" >/dev/null 2>&1
3
- }
4
-
5
- if command_exists winpty && test -t 1; then
6
- exec < /dev/tty
7
- fi
@@ -1,6 +0,0 @@
1
- dist
2
- node_modules
3
- auto-imports.d.ts
4
- components.d.ts
5
- **/*.html
6
-
@@ -1,6 +0,0 @@
1
- module.exports = {
2
- extends: [
3
- require.resolve('@citruslime/config/eslint'),
4
- './.eslintrc-auto-import.json'
5
- ]
6
- };
@@ -1,8 +0,0 @@
1
- {
2
- "./**/*.+(js|cjs|mjs|ts|vue)": [
3
- "eslint --fix"
4
- ],
5
- "./**/*.(css|vue)": [
6
- "stylelint --fix"
7
- ]
8
- }
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- extends: [require.resolve('@citruslime/config/stylelint')]
3
- };