orrin-cli 0.1.0__tar.gz → 0.1.4__tar.gz

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.
@@ -1,7 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orrin-cli
3
- Version: 0.1.0
3
+ Version: 0.1.4
4
4
  Summary: Orrin CLI
5
5
  Requires-Python: >=3.9
6
6
  Requires-Dist: typer
7
7
  Requires-Dist: requests
8
+ Requires-Dist: platformdirs
@@ -0,0 +1,158 @@
1
+ import typer
2
+ import requests
3
+ import json
4
+ import os
5
+ from pathlib import Path
6
+ from platformdirs import user_config_dir
7
+
8
+ app = typer.Typer(help="""
9
+ Welcome to Orrin CLI v0.1.4!\n\n
10
+
11
+ Orrin CLI enables you to perform actions within your terminal that would otherwise require
12
+ an entire dashboard. Though there is a dashboard, Orrin CLI enables a feasible development
13
+ experience for all developers, as they can swiftly run a command to upload their frontend,
14
+ perform checks on their app review status, and more!
15
+ """, no_args_is_help=True)
16
+
17
+ config = typer.Typer(help="Configure your Orrin Apps developer API with Orrin CLI")
18
+ app.add_typer(config, name='config')
19
+
20
+ ui = typer.Typer(help="UI related commands")
21
+ app.add_typer(ui, name="ui")
22
+
23
+ API_BASE = "http://192.168.1.153:8080"
24
+
25
+ APP_NAME = "orrin"
26
+ APP_AUTHOR = "orrin" # optional but recommended on Windows
27
+
28
+ config_dir = Path(user_config_dir(APP_NAME, APP_AUTHOR))
29
+ config_dir.mkdir(parents=True, exist_ok=True)
30
+
31
+ config_file = config_dir / "config.json"
32
+
33
+ # ---- Configuration based commands/helper functions ----
34
+
35
+ def save_api_key(api_key: str):
36
+ data = {"api_key": api_key}
37
+ with open(config_file, "w") as f:
38
+ json.dump(data, f)
39
+
40
+ def load_api_key() -> str | None:
41
+ if not config_file.exists():
42
+ return None
43
+ with open(config_file) as f:
44
+ return json.load(f).get("api_key")
45
+
46
+ @config.command(help="Add your Developer API key to the Orrin CLI to perform tasks explicitly relating to your developer account")
47
+ def configure_dev_api():
48
+ dev_api = typer.prompt(
49
+ "Enter your Developer API key",
50
+ hide_input=True,
51
+ confirmation_prompt=True,
52
+ )
53
+
54
+ resp = requests.post(
55
+ f'{API_BASE}/api/orrin_apps/developer_api_exists',
56
+ json={'developer_api_key': dev_api}
57
+ )
58
+
59
+ if not resp.ok:
60
+ typer.echo(f'❌ No developer account was found with API key:\n\n{dev_api}')
61
+ raise typer.Exit(1)
62
+
63
+ save_api_key(dev_api)
64
+ typer.echo("✅ Developer API configured with Orrin CLI")
65
+
66
+ @config.command(help='Revokes the Developer API currently configured with Orrin CLI')
67
+ def revoke_config():
68
+ if not config_file.exists():
69
+ typer.echo("ℹ️ No configuration found to revoke.")
70
+ raise typer.Exit(code=0)
71
+
72
+ try:
73
+ config_file.unlink()
74
+ typer.echo("✅ Credentials revoked. Local config removed.")
75
+ except Exception as e:
76
+ typer.echo(f"❌ Failed to revoke credentials: {e}")
77
+ raise typer.Exit(code=1)
78
+
79
+ @config.command(help='Show configured Developer API key')
80
+ def show_configuration():
81
+ if not config_file.exists():
82
+ typer.echo("ℹ️ No Developer API key configured with Orrin CLI")
83
+ raise typer.Exit(code=0)
84
+
85
+ dev_api_key = load_api_key()
86
+
87
+ typer.echo(f'Configured Developer API key: {dev_api_key}')
88
+
89
+ # -------------------------------------------------------
90
+
91
+ # ---- UI based commands/helper functions ----
92
+
93
+ @ui.command(help='''Build static output for next.js code, and generate a zip file to be uploaded.\n\nEnsure you have the following in next.config.tsx:\n\n
94
+ ------------------------------------------------------\n\n
95
+ /** @type {import('next').NextConfig} */\n\n
96
+ const nextConfig = {\n\n
97
+ output: 'export',\n\n
98
+ trailingSlash: true,\n\n
99
+ basePath: '/<your_app_name>/current',\n\n
100
+ reactStrictMode: true,\n\n
101
+ };\n\n
102
+ \n\n
103
+ module.exports = nextConfig;
104
+ ------------------------------------------------------\n\n
105
+ \n\n
106
+ Where <your_app_name> is the name of your app, which was configured in your backend.
107
+ ''')
108
+ def generate_zip():
109
+ os.system('npm install && npm run build')
110
+ os.system('cd out && zip -r ../ui-build.zip .')
111
+
112
+ @ui.command(help="Upload your frontend code to be reviewed")
113
+ def upload(
114
+ #zip_path: Path = typer.Argument(..., exists=True),
115
+ app_name: str = typer.Option(..., "--app")
116
+ ):
117
+ """
118
+ Upload a UI zip to Orrin.
119
+ """
120
+ if not os.path.isfile(os.path.join(os.getcwd(), 'ui-build.zip')):
121
+ typer.echo(f"❌ Path {os.path.join(os.getcwd(), 'ui-build.zip')} does not exist.\n\nEnsure you run `orrin ui generate-zip`, or build the zip yourself.")
122
+ raise typer.Exit(1)
123
+
124
+ dev_api = load_api_key()
125
+
126
+ if dev_api is None:
127
+ typer.echo("❌ You have not configured an API key. Please register with `orrin configure configure-dev-api`.")
128
+ raise typer.Exit(1)
129
+
130
+ with open(os.path.join(os.getcwd(), 'ui-build.zip'), "rb") as f:
131
+ response = requests.post(
132
+ f"{API_BASE}/ui/upload",
133
+ files={"file": f},
134
+ data={
135
+ "developer_id": dev_api,
136
+ "app_name": app_name
137
+ }
138
+ )
139
+
140
+ if response.status_code != 200:
141
+ try:
142
+ data = response.json()
143
+ typer.echo(f'❌ Upload failed: {response.status_code}\n\nMessage: {data["Message"]}')
144
+ except:
145
+ typer.echo("❌ Upload failed")
146
+ raise typer.Exit(1)
147
+
148
+ data = response.json()
149
+ typer.echo("✅ Uploaded")
150
+ typer.echo(f"Upload ID: {data.get('upload_id')}")
151
+
152
+ # --------------------------------------------
153
+
154
+ def main():
155
+ app()
156
+
157
+ if __name__ == "__main__":
158
+ main()
@@ -1,7 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orrin-cli
3
- Version: 0.1.0
3
+ Version: 0.1.4
4
4
  Summary: Orrin CLI
5
5
  Requires-Python: >=3.9
6
6
  Requires-Dist: typer
7
7
  Requires-Dist: requests
8
+ Requires-Dist: platformdirs
@@ -1,2 +1,3 @@
1
1
  typer
2
2
  requests
3
+ platformdirs
@@ -1,11 +1,12 @@
1
1
  [project]
2
2
  name = "orrin-cli"
3
- version = "0.1.0"
3
+ version = "0.1.4"
4
4
  description = "Orrin CLI"
5
5
  requires-python = ">=3.9"
6
6
  dependencies = [
7
7
  "typer",
8
- "requests"
8
+ "requests",
9
+ "platformdirs"
9
10
  ]
10
11
 
11
12
  [project.scripts]
@@ -1,36 +0,0 @@
1
- import typer
2
- import requests
3
- from pathlib import Path
4
-
5
- app = typer.Typer()
6
-
7
- API_BASE = "https://api.stellr-company.com"
8
-
9
- @app.command()
10
- def upload(
11
- zip_path: Path = typer.Argument(..., exists=True),
12
- app_name: str = typer.Option(..., "--app")
13
- ):
14
- """
15
- Upload a UI zip to Orrin.
16
- """
17
- with open(zip_path, "rb") as f:
18
- response = requests.post(
19
- f"{API_BASE}/ui/upload",
20
- files={"file": f},
21
- data={"app_name": app_name}
22
- )
23
-
24
- if response.status_code != 200:
25
- typer.echo("❌ Upload failed")
26
- raise typer.Exit(1)
27
-
28
- data = response.json()
29
- typer.echo("✅ Uploaded")
30
- typer.echo(f"Upload ID: {data.get('upload_id')}")
31
-
32
- def main():
33
- app()
34
-
35
- if __name__ == "__main__":
36
- main()
File without changes
File without changes