@xrift/cli 0.1.7 → 0.2.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
@@ -4,20 +4,76 @@ XRift のワールドやアバターをコマンドラインからアップロ
4
4
 
5
5
  ## 機能
6
6
 
7
+ - 新規プロジェクトの作成(テンプレートから)
7
8
  - ブラウザ認証によるログイン
8
9
  - ワールドのアップロード(複数ファイル対応)
9
10
  - 新規作成と更新の自動判定
10
11
  - アップロード進捗の可視化
11
12
 
13
+ ## クイックスタート
14
+
15
+ ```bash
16
+ # 新規プロジェクトを作成
17
+ npx @xrift/cli create my-world
18
+
19
+ # プロジェクトに移動
20
+ cd my-world
21
+
22
+ # 開発サーバーを起動
23
+ npm run dev
24
+
25
+ # ビルド
26
+ npm run build
27
+
28
+ # XRiftにログイン
29
+ npx @xrift/cli login
30
+
31
+ # ワールドをアップロード
32
+ npx @xrift/cli upload world
33
+ ```
34
+
12
35
  ## インストール
13
36
 
37
+ グローバルインストール(オプション):
38
+
14
39
  ```bash
15
40
  npm install -g @xrift/cli
16
41
  ```
17
42
 
43
+ グローバルインストールしない場合は `npx @xrift/cli` で実行できます。
44
+
18
45
  ## 使い方
19
46
 
20
- ### 1. ログイン
47
+ ### 1. 新規プロジェクトを作成
48
+
49
+ テンプレートから新しいワールドプロジェクトを作成します。
50
+
51
+ ```bash
52
+ # npx で実行(推奨)
53
+ npx @xrift/cli create my-world
54
+
55
+ # またはグローバルインストール後
56
+ xrift create my-world
57
+ ```
58
+
59
+ オプション:
60
+
61
+ ```bash
62
+ # カスタムテンプレートを使用
63
+ xrift create my-world --template WebXR-JP/custom-template
64
+
65
+ # 依存関係のインストールをスキップ
66
+ xrift create my-world --skip-install
67
+ ```
68
+
69
+ 作成されたプロジェクトには以下が含まれます:
70
+ - React Three Fiber + Three.js のセットアップ
71
+ - Rapier 物理エンジンの統合
72
+ - Vite ビルド設定
73
+ - TypeScript 設定
74
+ - 開発用サンプルワールド
75
+
76
+ ### 2. ログイン
21
77
 
22
78
  まず、ブラウザ認証でログインします。
23
79
 
@@ -27,7 +83,7 @@ xrift login
27
83
 
28
84
  ブラウザが自動的に開き、XRift での認証を行います。認証が完了すると、トークンが `~/.xrift/config.json` に保存されます。
29
85
 
30
- ### 2. プロジェクト設定
86
+ ### 3. プロジェクト設定
31
87
 
32
88
  プロジェクトのルートディレクトリに `xrift.json` を作成します。
33
89
 
@@ -41,7 +97,9 @@ xrift login
41
97
 
42
98
  - `distDir`: アップロードするビルド済みファイルが格納されているディレクトリ
43
99
 
44
- ### 3. ワールドをアップロード
100
+ 注:`xrift create` で作成したプロジェクトには自動的に `xrift.json` が含まれています。
101
+
102
+ ### 4. ワールドをアップロード
45
103
 
46
104
  ```bash
47
105
  xrift upload world
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const createCommand: Command;
3
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkDpC,eAAO,MAAM,aAAa,SAqFtB,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { Command } from 'commander';
2
+ import { resolve } from 'path';
3
+ import { access, constants, readdir } from 'fs';
4
+ import chalk from 'chalk';
5
+ import { downloadTemplate, customizeProject, installDependencies, } from '../lib/template.js';
6
+ /**
7
+ * ファイルまたはディレクトリが存在するかチェック
8
+ */
9
+ async function pathExists(path) {
10
+ try {
11
+ await new Promise((resolve, reject) => {
12
+ access(path, constants.F_OK, (err) => {
13
+ if (err)
14
+ reject(err);
15
+ else
16
+ resolve();
17
+ });
18
+ });
19
+ return true;
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ /**
26
+ * ディレクトリが空かチェック
27
+ */
28
+ async function isDirectoryEmpty(path) {
29
+ return new Promise((resolve, reject) => {
30
+ readdir(path, (err, files) => {
31
+ if (err) {
32
+ reject(err);
33
+ }
34
+ else {
35
+ // .git などの隠しファイルを除外
36
+ const visibleFiles = files.filter((file) => !file.startsWith('.'));
37
+ resolve(visibleFiles.length === 0);
38
+ }
39
+ });
40
+ });
41
+ }
42
+ export const createCommand = new Command('create')
43
+ .argument('<project-name>', 'プロジェクト名')
44
+ .option('-t, --template <repository>', 'テンプレートリポジトリ(例: WebXR-JP/xrift-world-template)', 'WebXR-JP/xrift-test-world')
45
+ .option('--skip-install', '依存関係のインストールをスキップ')
46
+ .option('--here', 'カレントディレクトリに直接作成')
47
+ .description('新しいXRiftプロジェクトを作成')
48
+ .action(async (projectName, options) => {
49
+ try {
50
+ console.log(chalk.cyan(`\n✨ XRiftワールドを作成します...\n`));
51
+ // プロジェクト名のバリデーション
52
+ if (!/^[a-z0-9-]+$/.test(projectName)) {
53
+ console.error(chalk.red('エラー: プロジェクト名は小文字の英数字とハイフンのみ使用できます'));
54
+ process.exit(1);
55
+ }
56
+ // プロジェクトパスの設定
57
+ let projectPath;
58
+ if (options.here) {
59
+ // カレントディレクトリに作成
60
+ projectPath = process.cwd();
61
+ // カレントディレクトリが空かチェック
62
+ const isEmpty = await isDirectoryEmpty(projectPath);
63
+ if (!isEmpty) {
64
+ console.log(chalk.yellow('⚠️ カレントディレクトリは空ではありません。既存のファイルは上書きされる可能性があります。'));
65
+ }
66
+ }
67
+ else {
68
+ // 新しいディレクトリを作成
69
+ projectPath = resolve(process.cwd(), projectName);
70
+ // 既存ディレクトリのチェック
71
+ const exists = await pathExists(projectPath);
72
+ if (exists) {
73
+ console.error(chalk.red(`エラー: ディレクトリ "${projectName}" は既に存在します`));
74
+ process.exit(1);
75
+ }
76
+ }
77
+ // テンプレートのダウンロード
78
+ await downloadTemplate(options.template, projectPath);
79
+ // プロジェクトのカスタマイズ
80
+ await customizeProject(projectName, projectPath);
81
+ // 依存関係のインストール
82
+ if (!options.skipInstall) {
83
+ await installDependencies(projectPath);
84
+ }
85
+ // 完了メッセージ
86
+ console.log(chalk.green('\n✅ プロジェクトが作成されました!\n'));
87
+ console.log(chalk.cyan('次のステップ:'));
88
+ if (!options.here) {
89
+ console.log(` ${chalk.yellow(`cd ${projectName}`)}`);
90
+ }
91
+ if (options.skipInstall) {
92
+ console.log(` ${chalk.yellow('npm install')} # 依存関係をインストール`);
93
+ }
94
+ console.log(` ${chalk.yellow('npm run dev')} # 開発サーバー起動`);
95
+ console.log(` ${chalk.yellow('npm run build')} # ビルド`);
96
+ console.log(` ${chalk.yellow('xrift upload world')} # XRiftにアップロード\n`);
97
+ }
98
+ catch (error) {
99
+ if (error instanceof Error) {
100
+ console.error(chalk.red('\nエラー:'), error.message);
101
+ }
102
+ else {
103
+ console.error(chalk.red('\n予期しないエラーが発生しました'));
104
+ }
105
+ process.exit(1);
106
+ }
107
+ });
108
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/commands/create.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ import { Command } from 'commander';
3
3
  import { readFileSync } from 'node:fs';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { dirname, join } from 'node:path';
6
+ import { createCommand } from './commands/create.js';
6
7
  import { loginCommand } from './commands/login.js';
7
8
  import { logoutCommand } from './commands/logout.js';
8
9
  import { whoamiCommand } from './commands/whoami.js';
@@ -17,6 +18,7 @@ program
17
18
  .description('XRift CLI - Upload worlds and avatars to XRift')
18
19
  .version(packageJson.version);
19
20
  // Register commands
21
+ program.addCommand(createCommand);
20
22
  program.addCommand(loginCommand);
21
23
  program.addCommand(logoutCommand);
22
24
  program.addCommand(whoamiCommand);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,4BAA4B;AAC5B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAC1D,CAAC;AAEF,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAEhC,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,4BAA4B;AAC5B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAC5B,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAC1D,CAAC;AAEF,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAEhC,oBAAoB;AACpB,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * GitHubからテンプレートをダウンロードする
3
+ */
4
+ export declare function downloadTemplate(template: string, destination: string): Promise<void>;
5
+ /**
6
+ * プロジェクトファイルをカスタマイズする
7
+ */
8
+ export declare function customizeProject(projectName: string, projectPath: string): Promise<void>;
9
+ /**
10
+ * 依存関係をインストールする
11
+ */
12
+ export declare function installDependencies(projectPath: string): Promise<void>;
13
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/lib/template.ts"],"names":[],"mappings":"AAmBA;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAaf;AAkCD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB5E"}
@@ -0,0 +1,118 @@
1
+ import { downloadTemplate as gigetDownload } from 'giget';
2
+ import { readFile, writeFile, access } from 'fs/promises';
3
+ import { constants } from 'fs';
4
+ import { join } from 'path';
5
+ import { spawn } from 'child_process';
6
+ import ora from 'ora';
7
+ /**
8
+ * ファイルまたはディレクトリが存在するかチェック
9
+ */
10
+ async function pathExists(path) {
11
+ try {
12
+ await access(path, constants.F_OK);
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ /**
20
+ * GitHubからテンプレートをダウンロードする
21
+ */
22
+ export async function downloadTemplate(template, destination) {
23
+ const spinner = ora('テンプレートをダウンロード中...').start();
24
+ try {
25
+ await gigetDownload(`github:${template}`, {
26
+ dir: destination,
27
+ force: true, // 既存ディレクトリへの展開を許可
28
+ });
29
+ spinner.succeed('テンプレートをダウンロードしました');
30
+ }
31
+ catch (error) {
32
+ spinner.fail('テンプレートのダウンロードに失敗しました');
33
+ throw error;
34
+ }
35
+ }
36
+ /**
37
+ * プロジェクト名をkebab-caseからsnake_caseに変換
38
+ */
39
+ function toSnakeCase(str) {
40
+ return str.replace(/-/g, '_');
41
+ }
42
+ /**
43
+ * ファイル内の文字列を置換する
44
+ */
45
+ async function replaceInFile(filePath, replacements) {
46
+ const exists = await pathExists(filePath);
47
+ if (!exists) {
48
+ return;
49
+ }
50
+ let content = await readFile(filePath, 'utf-8');
51
+ for (const { from, to } of replacements) {
52
+ if (typeof from === 'string') {
53
+ content = content.split(from).join(to);
54
+ }
55
+ else {
56
+ content = content.replace(from, to);
57
+ }
58
+ }
59
+ await writeFile(filePath, content, 'utf-8');
60
+ }
61
+ /**
62
+ * プロジェクトファイルをカスタマイズする
63
+ */
64
+ export async function customizeProject(projectName, projectPath) {
65
+ const spinner = ora('プロジェクトをカスタマイズ中...').start();
66
+ try {
67
+ const snakeCaseName = toSnakeCase(projectName);
68
+ // package.json を更新
69
+ await replaceInFile(join(projectPath, 'package.json'), [
70
+ { from: '@xrift/test-world', to: `@xrift/${projectName}` },
71
+ { from: '@xrift/world-template', to: `@xrift/${projectName}` },
72
+ { from: '"version": "0.2.1"', to: '"version": "0.1.0"' },
73
+ { from: '"version": "1.0.0"', to: '"version": "0.1.0"' },
74
+ ]);
75
+ // vite.config.ts を更新
76
+ await replaceInFile(join(projectPath, 'vite.config.ts'), [
77
+ { from: 'xrift_test_world', to: `xrift_${snakeCaseName}` },
78
+ { from: 'xrift_world_template', to: `xrift_${snakeCaseName}` },
79
+ ]);
80
+ // index.html を更新
81
+ await replaceInFile(join(projectPath, 'index.html'), [
82
+ { from: '<title>XRift Test World</title>', to: `<title>${projectName}</title>` },
83
+ { from: '<title>XRift World Template</title>', to: `<title>${projectName}</title>` },
84
+ ]);
85
+ spinner.succeed('プロジェクトをカスタマイズしました');
86
+ }
87
+ catch (error) {
88
+ spinner.fail('プロジェクトのカスタマイズに失敗しました');
89
+ throw error;
90
+ }
91
+ }
92
+ /**
93
+ * 依存関係をインストールする
94
+ */
95
+ export async function installDependencies(projectPath) {
96
+ const spinner = ora('依存関係をインストール中...').start();
97
+ return new Promise((resolve, reject) => {
98
+ const npm = spawn('npm', ['install'], {
99
+ cwd: projectPath,
100
+ stdio: 'pipe',
101
+ });
102
+ npm.on('close', (code) => {
103
+ if (code === 0) {
104
+ spinner.succeed('依存関係をインストールしました');
105
+ resolve();
106
+ }
107
+ else {
108
+ spinner.fail('依存関係のインストールに失敗しました');
109
+ reject(new Error(`npm install exited with code ${code}`));
110
+ }
111
+ });
112
+ npm.on('error', (error) => {
113
+ spinner.fail('依存関係のインストールに失敗しました');
114
+ reject(error);
115
+ });
116
+ });
117
+ }
118
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/lib/template.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xrift/cli",
3
- "version": "0.1.7",
3
+ "version": "0.2.0",
4
4
  "description": "XRift CLI tool for world and avatar uploads",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -47,6 +47,7 @@
47
47
  "chalk": "^5.3.0",
48
48
  "cli-progress": "^3.12.0",
49
49
  "commander": "^12.1.0",
50
+ "giget": "^2.0.0",
50
51
  "open": "^10.1.0",
51
52
  "ora": "^8.1.1"
52
53
  },