@duonghieu0712z/create-tauri-vue-template 0.0.7 → 0.0.8

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.
@@ -16,10 +16,6 @@ export async function ensureTemplate(templateDir) {
16
16
  await import('../scripts/prepare-template.js');
17
17
  }
18
18
  }
19
- export async function writeEditorSettings(targetDir, packageDir) {
20
- await mkdir(resolve(targetDir, '.vscode'), { recursive: true });
21
- await copyFile(resolve(packageDir, 'assets', 'vscode-settings.json'), resolve(targetDir, '.vscode', 'settings.json'));
22
- }
23
19
  async function removeTemplateArtifacts(targetDir) {
24
20
  await Promise.all(['CHANGELOG.md', 'Changelog.md', 'changelog.md'].map((fileName) => rm(resolve(targetDir, fileName), { force: true })));
25
21
  }
@@ -44,6 +40,5 @@ export async function scaffoldProject(targetDir, packageDir, identity) {
44
40
  await cp(templateDir, targetDir, { recursive: true });
45
41
  await restorePackagedGitignore(targetDir);
46
42
  await removeTemplateArtifacts(targetDir);
47
- await writeEditorSettings(targetDir, packageDir);
48
43
  await renameProject(targetDir, identity);
49
44
  }
@@ -1,16 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { createWriteStream } from 'node:fs';
3
2
  import { copyFile, cp, mkdir, readdir, rm } from 'node:fs/promises';
4
3
  import { dirname, resolve } from 'node:path';
5
- import { pipeline } from 'node:stream/promises';
6
4
  import { fileURLToPath } from 'node:url';
7
- import { extract } from 'tar';
8
5
  const currentDir = dirname(fileURLToPath(import.meta.url));
9
6
  const packageDir = resolve(currentDir, '..', '..');
10
7
  const templateDir = resolve(packageDir, 'template');
11
- const archivePath = resolve(packageDir, '.tmp-template.tar.gz');
12
- const templateRepo = process.env.TAURI_VUE_TEMPLATE_REPO || 'duonghieu0712z/tauri-vue-template';
13
- const templateRef = process.env.TAURI_VUE_TEMPLATE_REF || 'main';
14
8
  const templateSourceDir = process.env.TAURI_VUE_TEMPLATE_SOURCE
15
9
  ? resolve(process.env.TAURI_VUE_TEMPLATE_SOURCE)
16
10
  : null;
@@ -18,9 +12,11 @@ const excludedPaths = new Set([
18
12
  '.git',
19
13
  '.eslintcache',
20
14
  'dist',
15
+ 'dist-ssr',
21
16
  'node_modules',
22
17
  'packages',
23
18
  'src-tauri/target',
19
+ 'src-tauri/gen/schemas',
24
20
  ]);
25
21
  const excludedFileNames = new Set(['changelog.md']);
26
22
  function normalizePath(path) {
@@ -29,7 +25,43 @@ function normalizePath(path) {
29
25
  function shouldInclude(relativePath) {
30
26
  const normalizedPath = normalizePath(relativePath);
31
27
  const fileName = normalizedPath.split('/').at(-1)?.toLowerCase();
32
- return !excludedPaths.has(normalizedPath) && !excludedFileNames.has(fileName ?? '');
28
+ const pathParts = normalizedPath.split('/');
29
+ if (!normalizedPath || excludedFileNames.has(fileName ?? '')) {
30
+ return false;
31
+ }
32
+ if (fileName?.endsWith('.log') ||
33
+ fileName?.startsWith('npm-debug.log') ||
34
+ fileName?.startsWith('yarn-debug.log') ||
35
+ fileName?.startsWith('yarn-error.log') ||
36
+ fileName?.startsWith('pnpm-debug.log') ||
37
+ fileName?.startsWith('lerna-debug.log') ||
38
+ fileName?.endsWith('.local') ||
39
+ fileName?.endsWith('.tsbuildinfo')) {
40
+ return false;
41
+ }
42
+ if (excludedPaths.has(normalizedPath) ||
43
+ [...excludedPaths].some((path) => normalizedPath.startsWith(`${path}/`))) {
44
+ return false;
45
+ }
46
+ if ((pathParts[0] === 'logs' ||
47
+ pathParts[0] === '.idea' ||
48
+ pathParts[0] === '.eslintcache' ||
49
+ pathParts[0] === 'node_modules' ||
50
+ pathParts[0] === 'dist' ||
51
+ pathParts[0] === 'dist-ssr') &&
52
+ pathParts.length >= 1) {
53
+ return false;
54
+ }
55
+ if (pathParts[0] === '.vscode' &&
56
+ normalizedPath !== '.vscode' &&
57
+ normalizedPath !== '.vscode/extensions.json' &&
58
+ normalizedPath !== '.vscode/settings.json') {
59
+ return false;
60
+ }
61
+ if (pathParts[0] === '.husky' && pathParts[1] === '_' && normalizedPath !== '.husky/_') {
62
+ return false;
63
+ }
64
+ return true;
33
65
  }
34
66
  async function copyTemplateSource(sourceDir) {
35
67
  await mkdir(templateDir, { recursive: true });
@@ -40,23 +72,6 @@ async function copyTemplateSource(sourceDir) {
40
72
  filter: (source) => shouldInclude(normalizePath(source).slice(normalizePath(sourceDir).length + 1)),
41
73
  }))));
42
74
  }
43
- async function downloadTemplateArchive() {
44
- const archiveUrl = `https://github.com/${templateRepo}/archive/${templateRef}.tar.gz`;
45
- const response = await fetch(archiveUrl);
46
- if (!response.ok || !response.body) {
47
- throw new Error(`Could not download template archive: ${archiveUrl}`);
48
- }
49
- await pipeline(response.body, createWriteStream(archivePath));
50
- }
51
- async function extractTemplateArchive() {
52
- await mkdir(templateDir, { recursive: true });
53
- await extract({
54
- file: archivePath,
55
- cwd: templateDir,
56
- strip: 1,
57
- filter: (path) => shouldInclude(path.split('/').slice(1).join('/')),
58
- });
59
- }
60
75
  async function stagePackagedGitignore() {
61
76
  async function visit(dir) {
62
77
  const entries = await readdir(dir, { withFileTypes: true });
@@ -68,6 +83,7 @@ async function stagePackagedGitignore() {
68
83
  }
69
84
  if (entry.isFile() && entry.name === '.gitignore') {
70
85
  await copyFile(entryPath, resolve(dir, '_gitignore'));
86
+ await rm(entryPath, { force: true });
71
87
  }
72
88
  }));
73
89
  }
@@ -80,15 +96,10 @@ async function stagePackagedGitignore() {
80
96
  }
81
97
  }
82
98
  }
83
- await rm(templateDir, { recursive: true, force: true });
84
- await rm(archivePath, { force: true });
85
- if (templateSourceDir) {
86
- await copyTemplateSource(templateSourceDir);
87
- }
88
- else {
89
- await downloadTemplateArchive();
90
- await extractTemplateArchive();
91
- await rm(archivePath, { force: true });
99
+ if (!templateSourceDir) {
100
+ throw new Error('TAURI_VUE_TEMPLATE_SOURCE is required to refresh the packaged template');
92
101
  }
102
+ await rm(templateDir, { recursive: true, force: true });
103
+ await copyTemplateSource(templateSourceDir);
93
104
  await stagePackagedGitignore();
94
105
  console.log(`Prepared template at ${templateDir}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duonghieu0712z/create-tauri-vue-template",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Create a Tauri 2 + Vue 3 desktop app from the tauri-vue-template starter.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,7 +10,6 @@
10
10
  "create-tauri-vue-template": "dist/bin/index.js"
11
11
  },
12
12
  "files": [
13
- "assets",
14
13
  "dist",
15
14
  "template"
16
15
  ],
@@ -20,8 +19,7 @@
20
19
  },
21
20
  "dependencies": {
22
21
  "cac": "^7.0.0",
23
- "picocolors": "^1.1.1",
24
- "tar": "^7.5.1"
22
+ "picocolors": "^1.1.1"
25
23
  },
26
24
  "devDependencies": {
27
25
  "@types/node": "^25.9.1",
@@ -1,7 +1,3 @@
1
1
  #!/bin/bash
2
2
 
3
3
  pnpm lint-staged
4
-
5
- cd src-tauri
6
- cargo fmt
7
- git add .
@@ -1,20 +1,8 @@
1
1
  # Tauri Vue Template
2
2
 
3
- A compact Tauri 2 + Vue 3 template for desktop apps. It includes TypeScript, Vite, Tailwind CSS 4, shadcn-vue conventions, typed Rust-to-TypeScript bindings through Specta, and GitHub Actions for code quality and release builds.
3
+ ## Setup
4
4
 
5
- ## Stack
6
-
7
- This template keeps the stack focused on the pieces that usually need project-level wiring:
8
-
9
- - [Tauri 2](https://tauri.app/) with [Rust](https://www.rust-lang.org/) for the desktop shell and backend commands
10
- - [Vue 3](https://vuejs.org/), [TypeScript](https://www.typescriptlang.org/), and [Vite](https://vite.dev/) for the frontend
11
- - [shadcn-vue](https://www.shadcn-vue.com/) conventions with [Tailwind CSS 4](https://tailwindcss.com/) and [Lucide Vue](https://lucide.dev/) for UI
12
- - [Specta](https://github.com/specta-rs/specta) and [tauri-specta](https://github.com/oscartbeaumont/tauri-specta) for generated Rust-to-TypeScript bindings
13
- - [Oxlint](https://oxc.rs/docs/guide/usage/linter.html), [ESLint](https://eslint.org/), and [Oxfmt](https://oxc.rs/docs/guide/usage/formatter.html) for linting and formatting
14
-
15
- ## Prerequisites
16
-
17
- Install Node.js, pnpm, Rust, and the Tauri system dependencies for your operating system. The package is configured for Node.js `^20.19.0 || >=22.12.0`; GitHub Actions currently use Node.js 24 and pnpm 11.
5
+ Install Node.js, pnpm, Rust, and the Tauri system dependencies for your operating system. This project requires Node.js `^20.19.0 || >=22.12.0`.
18
6
 
19
7
  On Ubuntu/Debian, install the Tauri Linux dependencies:
20
8
 
@@ -23,37 +11,21 @@ sudo apt-get update
23
11
  sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
24
12
  ```
25
13
 
26
- ## Create a New Project
27
-
28
- After publishing the create package, scaffold a new project with:
29
-
30
- ```bash
31
- pnpm create @duonghieu0712z/tauri-vue-template@latest
32
- ```
33
-
34
- Pass values directly when needed:
35
-
36
- ```bash
37
- pnpm create @duonghieu0712z/tauri-vue-template@latest my-app --name "My App" --id "com.example.my-app" --author "Your Name"
38
- ```
39
-
40
- The create package copies this template into the target directory, updates the package name, Tauri product name, application identifier, Rust crate names, release workflow metadata, and then leaves dependency installation to the new project.
41
-
42
- ## Development
43
-
44
- Install dependencies:
14
+ Install project dependencies:
45
15
 
46
16
  ```bash
47
17
  pnpm install
48
18
  ```
49
19
 
20
+ ## Local Development
21
+
50
22
  Run the desktop app in development mode:
51
23
 
52
24
  ```bash
53
25
  pnpm start
54
26
  ```
55
27
 
56
- ## Local Build
28
+ ## Build
57
29
 
58
30
  Build the full Tauri desktop app locally:
59
31
 
@@ -63,7 +35,7 @@ pnpm make
63
35
 
64
36
  The generated installers and bundles are written under `src-tauri/target/release/bundle/`.
65
37
 
66
- ## Quality Checks
38
+ ## Lint and Format
67
39
 
68
40
  Check formatting and linting:
69
41
 
@@ -79,41 +51,7 @@ pnpm format:fix
79
51
  pnpm lint:fix
80
52
  ```
81
53
 
82
- ## Rust and TypeScript Bridge
83
-
84
- Backend commands live in `src-tauri/src/command/` and are registered through `tauri-specta`. During debug builds, Specta exports TypeScript bindings to `src/generated/bindings.ts`, so frontend calls can use generated types instead of manually duplicated contracts.
85
-
86
- ## Rename the App
87
-
88
- After creating a new project from this template, update the application name and Tauri identifier:
89
-
90
- ```bash
91
- pnpm rename --name "My App" --id "com.example.my-app" --author "Your Name"
92
- ```
93
-
94
- Set the package name explicitly when needed:
95
-
96
- ```bash
97
- pnpm rename --name "My App" --id "com.example.my-app" --author "Your Name" --package "my-app"
98
- ```
99
-
100
- After renaming, review the updated project identity in:
101
-
102
- - `package.json`
103
- - `index.html`
104
- - `src-tauri/tauri.conf.json`
105
- - `src-tauri/Cargo.toml`
106
- - `src-tauri/src/main.rs`
107
- - `.github/workflows/release.yml`
108
-
109
- Regenerate lockfiles after renaming:
110
-
111
- ```bash
112
- pnpm install
113
- cargo check --manifest-path src-tauri/Cargo.toml
114
- ```
115
-
116
- ## Versioning and Releases
54
+ ## Version
117
55
 
118
56
  Bump the app version:
119
57
 
@@ -122,5 +60,3 @@ pnpm bump 0.1.0
122
60
  ```
123
61
 
124
62
  The version script updates `package.json`, `src-tauri/tauri.conf.json`, and `src-tauri/Cargo.toml`.
125
-
126
- The release workflow builds macOS, Linux, and Windows bundles with `tauri-apps/tauri-action`, then creates a GitHub Release with the generated installers attached.
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { parsePositionals, readJson, updateFile } from './utils.js';
3
+ import { readFile, writeFile } from 'node:fs/promises';
4
4
 
5
5
  function parseArgs() {
6
- const args = parsePositionals(process.argv.slice(2));
6
+ const args = process.argv.slice(2).filter((arg) => arg !== '--');
7
7
  if (args.length !== 1 || args[0].startsWith('--')) {
8
- throw new Error('Usage: node scripts/bump-version.js VERSION');
8
+ throw new Error('Usage: node bump-version.js VERSION');
9
9
  }
10
10
 
11
11
  return {
@@ -13,17 +13,21 @@ function parseArgs() {
13
13
  };
14
14
  }
15
15
 
16
- async function readCurrent() {
17
- const packageJson = await readJson('package.json');
16
+ function replaceAll(content, replacements) {
17
+ return replacements.reduce(
18
+ (updatedContent, [search, replacement]) => updatedContent.replace(search, replacement),
19
+ content,
20
+ );
21
+ }
18
22
 
19
- return {
20
- version: packageJson.version,
21
- };
23
+ async function updateFile(path, replacements) {
24
+ const content = await readFile(path, 'utf8');
25
+ await writeFile(path, replaceAll(content, replacements));
26
+ console.log(`Updated ${path}`);
22
27
  }
23
28
 
24
29
  async function main() {
25
30
  const options = parseArgs();
26
- await readCurrent();
27
31
 
28
32
  await updateFile('package.json', [[/^(\s*"version":\s*")[^"]+(")/m, `$1${options.version}$2`]]);
29
33
  await updateFile('src-tauri/tauri.conf.json', [
@@ -0,0 +1,8 @@
1
+ export default {
2
+ '*.{js,ts,tsx,vue,html,css,json,yml,yaml}': ['oxfmt'],
3
+ '*.{js,ts,tsx,vue}': ['oxlint --fix', 'eslint --fix'],
4
+ '*.rs': () => [
5
+ 'cargo fmt --manifest-path src-tauri/Cargo.toml',
6
+ 'cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings',
7
+ ],
8
+ };
@@ -20,8 +20,7 @@
20
20
  "lint:fix:eslint": "eslint --fix . --cache",
21
21
  "format": "oxfmt --check .",
22
22
  "format:fix": "oxfmt .",
23
- "bump": "node scripts/bump-version.js",
24
- "rename": "node scripts/rename-app.js",
23
+ "bump": "node bump-version.js",
25
24
  "prepare": "husky"
26
25
  },
27
26
  "dependencies": {
@@ -47,7 +46,7 @@
47
46
  "husky": "^9.1.7",
48
47
  "jiti": "^2.7.0",
49
48
  "lint-staged": "^17.0.5",
50
- "npm-run-all2": "^9.0.0",
49
+ "npm-run-all2": "^9.0.1",
51
50
  "oxfmt": "^0.51.0",
52
51
  "oxlint": "^1.66.0",
53
52
  "tailwindcss": "^4.3.0",
@@ -59,15 +58,6 @@
59
58
  "vite-plugin-vue-devtools": "^8.1.2",
60
59
  "vue-tsc": "^3.3.1"
61
60
  },
62
- "lint-staged": {
63
- "*.{js,ts,tsx,vue,html,css,json,yml,yaml}": [
64
- "oxfmt"
65
- ],
66
- "*.{js,ts,tsx,vue}": [
67
- "oxlint --fix",
68
- "eslint --fix"
69
- ]
70
- },
71
61
  "engines": {
72
62
  "node": "^20.19.0 || >=22.12.0"
73
63
  }
@@ -70,8 +70,8 @@ importers:
70
70
  specifier: ^17.0.5
71
71
  version: 17.0.5
72
72
  npm-run-all2:
73
- specifier: ^9.0.0
74
- version: 9.0.0
73
+ specifier: ^9.0.1
74
+ version: 9.0.1
75
75
  oxfmt:
76
76
  specifier: ^0.51.0
77
77
  version: 0.51.0
@@ -393,56 +393,48 @@ packages:
393
393
  engines: {node: ^20.19.0 || >=22.12.0}
394
394
  cpu: [arm64]
395
395
  os: [linux]
396
- libc: [glibc]
397
396
 
398
397
  '@oxfmt/binding-linux-arm64-musl@0.51.0':
399
398
  resolution: {integrity: sha512-KBUCdrH5bwVrAvI9gU/1S55oH6fzXjr++J/oVocdu7bYTks1l7DNNT+rLd/1TDdAEjObGwmfWamn7LC1m8A0DQ==}
400
399
  engines: {node: ^20.19.0 || >=22.12.0}
401
400
  cpu: [arm64]
402
401
  os: [linux]
403
- libc: [musl]
404
402
 
405
403
  '@oxfmt/binding-linux-ppc64-gnu@0.51.0':
406
404
  resolution: {integrity: sha512-NapfjYsABFqTJ1Dn9Efq6sN5esaHconVKwVLbDGNQLrwpOx/g17mkwErHzU72PutL67nf3wNAkbq122H+zLxag==}
407
405
  engines: {node: ^20.19.0 || >=22.12.0}
408
406
  cpu: [ppc64]
409
407
  os: [linux]
410
- libc: [glibc]
411
408
 
412
409
  '@oxfmt/binding-linux-riscv64-gnu@0.51.0':
413
410
  resolution: {integrity: sha512-5dlDt1dUZCVi6elIhiK1PWg9wpTzTcIuj0IZnSurvIoMrhOWqqTcc1dSTxcSkNaBZhfsNqRZdINI1zAgbKkJNQ==}
414
411
  engines: {node: ^20.19.0 || >=22.12.0}
415
412
  cpu: [riscv64]
416
413
  os: [linux]
417
- libc: [glibc]
418
414
 
419
415
  '@oxfmt/binding-linux-riscv64-musl@0.51.0':
420
416
  resolution: {integrity: sha512-pgdWUJn0S5nulyiVdlFV8DzCUnGXkU99W5PSkkmbaZW+LrZBPxpezun4G0DDHbQaVYuJeCuKsXsGKGo77CkUTQ==}
421
417
  engines: {node: ^20.19.0 || >=22.12.0}
422
418
  cpu: [riscv64]
423
419
  os: [linux]
424
- libc: [musl]
425
420
 
426
421
  '@oxfmt/binding-linux-s390x-gnu@0.51.0':
427
422
  resolution: {integrity: sha512-2XTFUe97CbDGAI8vjwDfZ1HdakO0XIADyJ24idEg64SC4/K4in/OisXVnrW4NMK7I6TgC7EqRhC0Ln/nKhAemA==}
428
423
  engines: {node: ^20.19.0 || >=22.12.0}
429
424
  cpu: [s390x]
430
425
  os: [linux]
431
- libc: [glibc]
432
426
 
433
427
  '@oxfmt/binding-linux-x64-gnu@0.51.0':
434
428
  resolution: {integrity: sha512-kQ1OuCqqt/yyf0ZN9VFxW1/JnlgJgii3Dr7pWf9vNBvrX1hv6g39/+mc5oGRHRGJFZtl3zsGDWR9c5N2B/gwBw==}
435
429
  engines: {node: ^20.19.0 || >=22.12.0}
436
430
  cpu: [x64]
437
431
  os: [linux]
438
- libc: [glibc]
439
432
 
440
433
  '@oxfmt/binding-linux-x64-musl@0.51.0':
441
434
  resolution: {integrity: sha512-ARTYqxHF475o96Gbn41hvSWSSRygPlRDXZZgZ9I2scU1y0qiWpCQyZCoefaQa0mwv+wwtZ+luS4YOzsRzM/izg==}
442
435
  engines: {node: ^20.19.0 || >=22.12.0}
443
436
  cpu: [x64]
444
437
  os: [linux]
445
- libc: [musl]
446
438
 
447
439
  '@oxfmt/binding-openharmony-arm64@0.51.0':
448
440
  resolution: {integrity: sha512-QiC1XrCl6a6BmqMzduO8hdIRMf1m44hCkt2Q68KWkTvUB/E7fd2iomyNh6KnnRca5w6eBrRAAtLFqTh+xjsjJA==}
@@ -515,56 +507,48 @@ packages:
515
507
  engines: {node: ^20.19.0 || >=22.12.0}
516
508
  cpu: [arm64]
517
509
  os: [linux]
518
- libc: [glibc]
519
510
 
520
511
  '@oxlint/binding-linux-arm64-musl@1.66.0':
521
512
  resolution: {integrity: sha512-hmo+ZB/lHkR1HdDmnziNpzSLmulnUSu10VEqX2Yex7OwvoBAbjJQLvy4gIBRV3AAwWnCvAxKp5Nv1GE6LU1QMg==}
522
513
  engines: {node: ^20.19.0 || >=22.12.0}
523
514
  cpu: [arm64]
524
515
  os: [linux]
525
- libc: [musl]
526
516
 
527
517
  '@oxlint/binding-linux-ppc64-gnu@1.66.0':
528
518
  resolution: {integrity: sha512-2Invd4Uyy81mVooQC5FBtfxSNrvcX1OxbMlVQ6M2erRrNI2awFYF26YNW2yFxdVFZ4ffNOWKghtMjhnUPsXsVA==}
529
519
  engines: {node: ^20.19.0 || >=22.12.0}
530
520
  cpu: [ppc64]
531
521
  os: [linux]
532
- libc: [glibc]
533
522
 
534
523
  '@oxlint/binding-linux-riscv64-gnu@1.66.0':
535
524
  resolution: {integrity: sha512-s0iXPDQVdgayE3RGa/N2DZF7tjgg0TwEtD1sGoDxqPDGrIXgo45H0yHknT0f9A0yteASsweYZtDyTuVlM4aSag==}
536
525
  engines: {node: ^20.19.0 || >=22.12.0}
537
526
  cpu: [riscv64]
538
527
  os: [linux]
539
- libc: [glibc]
540
528
 
541
529
  '@oxlint/binding-linux-riscv64-musl@1.66.0':
542
530
  resolution: {integrity: sha512-OekL4XFiu7RPK0JIZi8VeHgtIXPREf42t8Cy/rKEsC+P3gcqDgNAAGiyuUOpdbG4wwbfue1q4CHcCO7spSve6w==}
543
531
  engines: {node: ^20.19.0 || >=22.12.0}
544
532
  cpu: [riscv64]
545
533
  os: [linux]
546
- libc: [musl]
547
534
 
548
535
  '@oxlint/binding-linux-s390x-gnu@1.66.0':
549
536
  resolution: {integrity: sha512-Ga1D0kj1SFslm34ThA/BdkUlyAYEnTsXyRC4pF0C5agZSwtGdHYWMTQWemUfBGp4RCG4QWXgdO+HmmmKqOtlBg==}
550
537
  engines: {node: ^20.19.0 || >=22.12.0}
551
538
  cpu: [s390x]
552
539
  os: [linux]
553
- libc: [glibc]
554
540
 
555
541
  '@oxlint/binding-linux-x64-gnu@1.66.0':
556
542
  resolution: {integrity: sha512-p5jfP1wUZe/IC3qpQO84n9DRnf9g3lKRtLBlQq23ykyrDglHcVx7sWmVTlPuU6SBw8mNnPzyOn022G3XZHnlww==}
557
543
  engines: {node: ^20.19.0 || >=22.12.0}
558
544
  cpu: [x64]
559
545
  os: [linux]
560
- libc: [glibc]
561
546
 
562
547
  '@oxlint/binding-linux-x64-musl@1.66.0':
563
548
  resolution: {integrity: sha512-vUB/sYlYZorDL1ZD+o9mRv7zbsykrrFRtmgS6R8musZqLtrPRQn1gc1eGpuX+sfdccz42STl/AqldY6XRb2upQ==}
564
549
  engines: {node: ^20.19.0 || >=22.12.0}
565
550
  cpu: [x64]
566
551
  os: [linux]
567
- libc: [musl]
568
552
 
569
553
  '@oxlint/binding-openharmony-arm64@1.66.0':
570
554
  resolution: {integrity: sha512-yde+6p/F59xRkGR9H1HfngWRif1QRJjynZK349l+UI0H6w9hL3G8/AVaTHFyTtLVQ56qtNbX2/5Dc77n1ovnOg==}
@@ -632,42 +616,36 @@ packages:
632
616
  engines: {node: ^20.19.0 || >=22.12.0}
633
617
  cpu: [arm64]
634
618
  os: [linux]
635
- libc: [glibc]
636
619
 
637
620
  '@rolldown/binding-linux-arm64-musl@1.0.2':
638
621
  resolution: {integrity: sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==}
639
622
  engines: {node: ^20.19.0 || >=22.12.0}
640
623
  cpu: [arm64]
641
624
  os: [linux]
642
- libc: [musl]
643
625
 
644
626
  '@rolldown/binding-linux-ppc64-gnu@1.0.2':
645
627
  resolution: {integrity: sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==}
646
628
  engines: {node: ^20.19.0 || >=22.12.0}
647
629
  cpu: [ppc64]
648
630
  os: [linux]
649
- libc: [glibc]
650
631
 
651
632
  '@rolldown/binding-linux-s390x-gnu@1.0.2':
652
633
  resolution: {integrity: sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==}
653
634
  engines: {node: ^20.19.0 || >=22.12.0}
654
635
  cpu: [s390x]
655
636
  os: [linux]
656
- libc: [glibc]
657
637
 
658
638
  '@rolldown/binding-linux-x64-gnu@1.0.2':
659
639
  resolution: {integrity: sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==}
660
640
  engines: {node: ^20.19.0 || >=22.12.0}
661
641
  cpu: [x64]
662
642
  os: [linux]
663
- libc: [glibc]
664
643
 
665
644
  '@rolldown/binding-linux-x64-musl@1.0.2':
666
645
  resolution: {integrity: sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==}
667
646
  engines: {node: ^20.19.0 || >=22.12.0}
668
647
  cpu: [x64]
669
648
  os: [linux]
670
- libc: [musl]
671
649
 
672
650
  '@rolldown/binding-openharmony-arm64@1.0.2':
673
651
  resolution: {integrity: sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==}
@@ -733,28 +711,24 @@ packages:
733
711
  engines: {node: '>= 20'}
734
712
  cpu: [arm64]
735
713
  os: [linux]
736
- libc: [glibc]
737
714
 
738
715
  '@tailwindcss/oxide-linux-arm64-musl@4.3.0':
739
716
  resolution: {integrity: sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==}
740
717
  engines: {node: '>= 20'}
741
718
  cpu: [arm64]
742
719
  os: [linux]
743
- libc: [musl]
744
720
 
745
721
  '@tailwindcss/oxide-linux-x64-gnu@4.3.0':
746
722
  resolution: {integrity: sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==}
747
723
  engines: {node: '>= 20'}
748
724
  cpu: [x64]
749
725
  os: [linux]
750
- libc: [glibc]
751
726
 
752
727
  '@tailwindcss/oxide-linux-x64-musl@4.3.0':
753
728
  resolution: {integrity: sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==}
754
729
  engines: {node: '>= 20'}
755
730
  cpu: [x64]
756
731
  os: [linux]
757
- libc: [musl]
758
732
 
759
733
  '@tailwindcss/oxide-wasm32-wasi@4.3.0':
760
734
  resolution: {integrity: sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==}
@@ -815,35 +789,30 @@ packages:
815
789
  engines: {node: '>= 10'}
816
790
  cpu: [arm64]
817
791
  os: [linux]
818
- libc: [glibc]
819
792
 
820
793
  '@tauri-apps/cli-linux-arm64-musl@2.11.2':
821
794
  resolution: {integrity: sha512-X1rm0BERqAAggtYTESSgXrS3sz4Sb/OiPiz54UqISlXW+GkR3vNIGnsy/lejNmoXGVqri3Q53BCfQiclOIyRPw==}
822
795
  engines: {node: '>= 10'}
823
796
  cpu: [arm64]
824
797
  os: [linux]
825
- libc: [musl]
826
798
 
827
799
  '@tauri-apps/cli-linux-riscv64-gnu@2.11.2':
828
800
  resolution: {integrity: sha512-usbMLJbT3KtkOrBMDVeGYNM35aTHXx38SJSzTMSqqjeUIOQ+iVPjb2yAGNAE+KqmBbAx4FOFIyMeKXx2M/JKGQ==}
829
801
  engines: {node: '>= 10'}
830
802
  cpu: [riscv64]
831
803
  os: [linux]
832
- libc: [glibc]
833
804
 
834
805
  '@tauri-apps/cli-linux-x64-gnu@2.11.2':
835
806
  resolution: {integrity: sha512-Ru4gwJKPG0ctVGchRGpRup4Y4lW2SSfFnrbQcyHhCliKy4g8Qz97TrUgCur4CbWyAgKxvGh3SjrkA0LDYzDGiw==}
836
807
  engines: {node: '>= 10'}
837
808
  cpu: [x64]
838
809
  os: [linux]
839
- libc: [glibc]
840
810
 
841
811
  '@tauri-apps/cli-linux-x64-musl@2.11.2':
842
812
  resolution: {integrity: sha512-eUm7T6clN1MMmNSRQ9gaWsQdyehQx2Gmn5hht/QUlqZQI/qcP2OJK5dnaxqwFzCr2HdsEo9ydxaqcS1oJzMvUw==}
843
813
  engines: {node: '>= 10'}
844
814
  cpu: [x64]
845
815
  os: [linux]
846
- libc: [musl]
847
816
 
848
817
  '@tauri-apps/cli-win32-arm64-msvc@2.11.2':
849
818
  resolution: {integrity: sha512-HeeZW80jU+gVTOEX4X/hC6NVSAdDVXajwP5fxIZ/3z9WvUC7qrudX2GMTilYq6Dg0e0sk0XgsAJD1hZ5wPBXUA==}
@@ -1518,28 +1487,24 @@ packages:
1518
1487
  engines: {node: '>= 12.0.0'}
1519
1488
  cpu: [arm64]
1520
1489
  os: [linux]
1521
- libc: [glibc]
1522
1490
 
1523
1491
  lightningcss-linux-arm64-musl@1.32.0:
1524
1492
  resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==}
1525
1493
  engines: {node: '>= 12.0.0'}
1526
1494
  cpu: [arm64]
1527
1495
  os: [linux]
1528
- libc: [musl]
1529
1496
 
1530
1497
  lightningcss-linux-x64-gnu@1.32.0:
1531
1498
  resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==}
1532
1499
  engines: {node: '>= 12.0.0'}
1533
1500
  cpu: [x64]
1534
1501
  os: [linux]
1535
- libc: [glibc]
1536
1502
 
1537
1503
  lightningcss-linux-x64-musl@1.32.0:
1538
1504
  resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==}
1539
1505
  engines: {node: '>= 12.0.0'}
1540
1506
  cpu: [x64]
1541
1507
  os: [linux]
1542
- libc: [musl]
1543
1508
 
1544
1509
  lightningcss-win32-arm64-msvc@1.32.0:
1545
1510
  resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==}
@@ -1633,8 +1598,8 @@ packages:
1633
1598
  resolution: {integrity: sha512-tdt4aFn9QamlhdN3HV2D2ccpBwO5/fyjjbXUxYA6uBjyekMZcZvDq0aSj9t5Jo+tih6AYFnt/cuIRn9013e0Uw==}
1634
1599
  engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
1635
1600
 
1636
- npm-run-all2@9.0.0:
1637
- resolution: {integrity: sha512-NMHaiMWl+kotdoAzVtwElvEh4PLdjAGsdmCJXOGv0rdM4d19FGIa0z0ISFuMklmYgVgQzS4h+jNlowz+q1aojw==}
1601
+ npm-run-all2@9.0.1:
1602
+ resolution: {integrity: sha512-ZtK8WXZBUA9x0XD6nxYdFLe86FxpkCTq2LiQxzX0LeXQY/vyAigQZXjjj/xfTwgV4Yqe/vYNIq2W09lrHKTcuQ==}
1638
1603
  engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0, npm: '>= 10'}
1639
1604
  hasBin: true
1640
1605
 
@@ -1808,8 +1773,8 @@ packages:
1808
1773
  resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1809
1774
  engines: {node: '>=8'}
1810
1775
 
1811
- shell-quote@1.8.3:
1812
- resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==}
1776
+ shell-quote@1.8.4:
1777
+ resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==}
1813
1778
  engines: {node: '>= 0.4'}
1814
1779
 
1815
1780
  signal-exit@4.1.0:
@@ -3448,7 +3413,7 @@ snapshots:
3448
3413
 
3449
3414
  npm-normalize-package-bin@6.0.0: {}
3450
3415
 
3451
- npm-run-all2@9.0.0:
3416
+ npm-run-all2@9.0.1:
3452
3417
  dependencies:
3453
3418
  ansi-styles: 6.2.3
3454
3419
  cross-spawn: 7.0.6
@@ -3456,7 +3421,7 @@ snapshots:
3456
3421
  picomatch: 4.0.4
3457
3422
  pidtree: 0.6.0
3458
3423
  read-package-json-fast: 6.0.0
3459
- shell-quote: 1.8.3
3424
+ shell-quote: 1.8.4
3460
3425
  which: 7.0.0
3461
3426
 
3462
3427
  nth-check@2.1.1:
@@ -3651,7 +3616,7 @@ snapshots:
3651
3616
 
3652
3617
  shebang-regex@3.0.0: {}
3653
3618
 
3654
- shell-quote@1.8.3: {}
3619
+ shell-quote@1.8.4: {}
3655
3620
 
3656
3621
  signal-exit@4.1.0: {}
3657
3622
 
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { readFile } from 'node:fs/promises';
4
-
5
- import { parseOptions, readJson, updateFile, writeJson, writeText } from './utils.js';
6
-
7
- function parseArgs() {
8
- const options = parseOptions(process.argv.slice(2));
9
-
10
- if (!options.name || !options.id) {
11
- throw new Error(
12
- 'Usage: node scripts/rename-app.js --name "App Name" --id "com.example.app" [--author "Author Name"]',
13
- );
14
- }
15
-
16
- return options;
17
- }
18
-
19
- function toKebabCase(value) {
20
- return value
21
- .trim()
22
- .replace(/['"]/g, '')
23
- .replace(/[^a-zA-Z0-9]+/g, '-')
24
- .replace(/^-+|-+$/g, '')
25
- .toLowerCase();
26
- }
27
-
28
- function toSnakeCase(value) {
29
- return toKebabCase(value).replaceAll('-', '_');
30
- }
31
-
32
- function replaceOne(content, pattern, replacement, description) {
33
- if (!pattern.test(content)) {
34
- throw new Error(`Could not update ${description}`);
35
- }
36
-
37
- return content.replace(pattern, replacement);
38
- }
39
-
40
- async function readCurrent() {
41
- const packageJson = await readJson('package.json');
42
- const tauriConfig = await readJson('src-tauri/tauri.conf.json');
43
- const cargoToml = await readFile('src-tauri/Cargo.toml', 'utf8');
44
-
45
- const crateName = cargoToml.match(/^name = "([^"]+)"/m)?.[1];
46
- const crateLibName = cargoToml.match(/^\[lib\]\s+[\s\S]*?^name = "([^"]+)"/m)?.[1];
47
- const author = cargoToml.match(/^authors = \["([^"]+)"\]/m)?.[1];
48
-
49
- if (
50
- !packageJson.name ||
51
- !tauriConfig.productName ||
52
- !tauriConfig.identifier ||
53
- !crateName ||
54
- !crateLibName ||
55
- !author
56
- ) {
57
- throw new Error('Could not read current project identity');
58
- }
59
- }
60
-
61
- async function main() {
62
- const options = parseArgs();
63
- await readCurrent();
64
- const appName = options.name.trim();
65
- const appId = options.id.trim();
66
- const author = options.author?.trim();
67
- const packageName = options.package?.trim() || toKebabCase(appName);
68
- const crateName = toKebabCase(packageName);
69
- const crateLibName = `${toSnakeCase(crateName)}_lib`;
70
-
71
- const packageJson = await readJson('package.json');
72
- packageJson.name = packageName;
73
- if (author) {
74
- packageJson.author = author;
75
- }
76
-
77
- await writeJson('package.json', packageJson);
78
-
79
- await updateFile('index.html', [[/<title>.*<\/title>/, `<title>${appName}</title>`]]);
80
-
81
- const tauriConfig = await readJson('src-tauri/tauri.conf.json');
82
- tauriConfig.productName = appName;
83
- tauriConfig.identifier = appId;
84
- tauriConfig.app.windows = tauriConfig.app.windows.map((window) => ({
85
- ...window,
86
- title: window.title ? appName : window.title,
87
- }));
88
- if (author) {
89
- tauriConfig.bundle.publisher = author;
90
- }
91
-
92
- await writeJson('src-tauri/tauri.conf.json', tauriConfig);
93
-
94
- let cargoToml = await readFile('src-tauri/Cargo.toml', 'utf8');
95
- cargoToml = replaceOne(
96
- cargoToml,
97
- /^name = "([^"]+)"/m,
98
- `name = "${crateName}"`,
99
- 'Cargo package name',
100
- );
101
- cargoToml = replaceOne(
102
- cargoToml,
103
- /^description = "([^"]+)"/m,
104
- `description = "${appName}"`,
105
- 'Cargo description',
106
- );
107
- if (author) {
108
- cargoToml = replaceOne(
109
- cargoToml,
110
- /^authors = \[[^\]]*\]/m,
111
- `authors = ["${author}"]`,
112
- 'Cargo authors',
113
- );
114
- }
115
- cargoToml = replaceOne(
116
- cargoToml,
117
- /^(\[lib\]\s+[\s\S]*?^name = )"([^"]+)"/m,
118
- `$1"${crateLibName}"`,
119
- 'Cargo lib name',
120
- );
121
- await writeText('src-tauri/Cargo.toml', cargoToml);
122
-
123
- await updateFile('src-tauri/src/main.rs', [
124
- [/^[a-zA-Z0-9_]+_lib::run\(\);$/m, `${crateLibName}::run();`],
125
- ]);
126
-
127
- await updateFile('.github/workflows/release.yml', [
128
- [/^(\s*releaseName:\s*).*$/m, `$1${appName} v__VERSION__`],
129
- ]);
130
- }
131
-
132
- try {
133
- await main();
134
- } catch (error) {
135
- console.error(error.message);
136
- process.exit(1);
137
- }
@@ -1,59 +0,0 @@
1
- import { readFile, writeFile } from 'node:fs/promises';
2
-
3
- export function parseOptions(args) {
4
- const options = {};
5
- const normalizedArgs = args.filter((arg) => arg !== '--');
6
-
7
- for (let index = 0; index < normalizedArgs.length; index += 1) {
8
- const arg = normalizedArgs[index];
9
- if (!arg.startsWith('--')) {
10
- throw new Error(`Unexpected argument: ${arg}`);
11
- }
12
-
13
- const key = arg.slice(2);
14
- const value = normalizedArgs[index + 1];
15
- if (!value || value.startsWith('--')) {
16
- throw new Error(`Missing value for --${key}`);
17
- }
18
-
19
- options[key] = value;
20
- index += 1;
21
- }
22
-
23
- return options;
24
- }
25
-
26
- export function parsePositionals(args) {
27
- return args.filter((arg) => arg !== '--');
28
- }
29
-
30
- export function replaceAll(content, replacements) {
31
- return replacements.reduce((updatedContent, [search, replacement]) => {
32
- if (search instanceof RegExp) {
33
- return updatedContent.replace(search, replacement);
34
- }
35
-
36
- return updatedContent.replaceAll(search, replacement);
37
- }, content);
38
- }
39
-
40
- export async function readJson(path) {
41
- return JSON.parse(await readFile(path, 'utf8'));
42
- }
43
-
44
- export async function writeJson(path, value) {
45
- await writeFile(path, `${JSON.stringify(value, null, 4)}\n`);
46
- console.log(`Updated ${path}`);
47
- }
48
-
49
- export async function writeText(path, value) {
50
- await writeFile(path, value);
51
- console.log(`Updated ${path}`);
52
- }
53
-
54
- export async function updateFile(path, replacements) {
55
- const content = await readFile(path, 'utf8');
56
- const updatedContent = replaceAll(content, replacements);
57
- await writeFile(path, updatedContent);
58
- console.log(`Updated ${path}`);
59
- }