@trendify/cli 0.1.4

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.
Files changed (60) hide show
  1. package/.env.example +2 -0
  2. package/README.md +52 -0
  3. package/dist/app.d.ts +6 -0
  4. package/dist/app.d.ts.map +1 -0
  5. package/dist/app.js +300 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +28 -0
  9. package/dist/config/app-paths.d.ts +4 -0
  10. package/dist/config/app-paths.d.ts.map +1 -0
  11. package/dist/config/app-paths.js +5 -0
  12. package/dist/config/env.d.ts +14 -0
  13. package/dist/config/env.d.ts.map +1 -0
  14. package/dist/config/env.js +58 -0
  15. package/dist/modules/auth/auth-service.d.ts +39 -0
  16. package/dist/modules/auth/auth-service.d.ts.map +1 -0
  17. package/dist/modules/auth/auth-service.js +288 -0
  18. package/dist/modules/auth/auth-storage.d.ts +11 -0
  19. package/dist/modules/auth/auth-storage.d.ts.map +1 -0
  20. package/dist/modules/auth/auth-storage.js +65 -0
  21. package/dist/modules/auth/auth-user.d.ts +3 -0
  22. package/dist/modules/auth/auth-user.d.ts.map +1 -0
  23. package/dist/modules/auth/auth-user.js +10 -0
  24. package/dist/modules/auth/page/login-page.d.ts +12 -0
  25. package/dist/modules/auth/page/login-page.d.ts.map +1 -0
  26. package/dist/modules/auth/page/login-page.js +22 -0
  27. package/dist/modules/discovery/components/discovery-step-header.d.ts +7 -0
  28. package/dist/modules/discovery/components/discovery-step-header.d.ts.map +1 -0
  29. package/dist/modules/discovery/components/discovery-step-header.js +5 -0
  30. package/dist/modules/discovery/page/discovery-page.d.ts +11 -0
  31. package/dist/modules/discovery/page/discovery-page.d.ts.map +1 -0
  32. package/dist/modules/discovery/page/discovery-page.js +58 -0
  33. package/dist/modules/profile/page/profile-page.d.ts +12 -0
  34. package/dist/modules/profile/page/profile-page.d.ts.map +1 -0
  35. package/dist/modules/profile/page/profile-page.js +180 -0
  36. package/dist/shared/components/action-menu-page.d.ts +13 -0
  37. package/dist/shared/components/action-menu-page.d.ts.map +1 -0
  38. package/dist/shared/components/action-menu-page.js +7 -0
  39. package/dist/shared/components/radio-select.d.ts +12 -0
  40. package/dist/shared/components/radio-select.d.ts.map +1 -0
  41. package/dist/shared/components/radio-select.js +16 -0
  42. package/dist/shared/components/step-header.d.ts +7 -0
  43. package/dist/shared/components/step-header.d.ts.map +1 -0
  44. package/dist/shared/components/step-header.js +5 -0
  45. package/dist/shared/components/text-field.d.ts +12 -0
  46. package/dist/shared/components/text-field.d.ts.map +1 -0
  47. package/dist/shared/components/text-field.js +6 -0
  48. package/dist/shared/template/app-logo.d.ts +2 -0
  49. package/dist/shared/template/app-logo.d.ts.map +1 -0
  50. package/dist/shared/template/app-logo.js +13 -0
  51. package/dist/shared/template/app-menu.d.ts +17 -0
  52. package/dist/shared/template/app-menu.d.ts.map +1 -0
  53. package/dist/shared/template/app-menu.js +85 -0
  54. package/dist/shared/template/app-shell.d.ts +12 -0
  55. package/dist/shared/template/app-shell.d.ts.map +1 -0
  56. package/dist/shared/template/app-shell.js +15 -0
  57. package/dist/version.d.ts +2 -0
  58. package/dist/version.d.ts.map +1 -0
  59. package/dist/version.js +1 -0
  60. package/package.json +44 -0
package/.env.example ADDED
@@ -0,0 +1,2 @@
1
+ SUPABASE_URL=
2
+ SUPABASE_PUBLISHABLE_DEFAULT_KEY=
package/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # Trendify CLI
2
+
3
+ CLI do Trendify feita com Ink. O pacote publicado no npm e `@trendify/cli`, mas o comando instalado globalmente continua sendo `trendify`.
4
+
5
+ ## Instalacao
6
+
7
+ Publicacao do pacote:
8
+
9
+ ```sh
10
+ npm install -g @trendify/cli
11
+ ```
12
+
13
+ Depois da instalacao, o comando continua sendo:
14
+
15
+ ```sh
16
+ trendify --help
17
+ ```
18
+
19
+ ## Ambiente
20
+
21
+ Crie `apps/cli/.env` a partir de `apps/cli/.env.example` ou exporte estas variaveis no shell:
22
+
23
+ ```sh
24
+ SUPABASE_URL=
25
+ SUPABASE_PUBLISHABLE_DEFAULT_KEY=
26
+ ```
27
+
28
+ A sessao autenticada fica persistida em `~/.trendify/auth/storage.json`.
29
+
30
+ ## Desenvolvimento local
31
+
32
+ ```sh
33
+ npm run dev --workspace apps/cli
34
+ npm run build --workspace apps/cli
35
+ npm run check-types --workspace apps/cli
36
+ ```
37
+
38
+ ## Release para npm
39
+
40
+ O fluxo oficial de publicacao fica na raiz do monorepo.
41
+
42
+ Se quiser guardar o token no projeto:
43
+
44
+ ```sh
45
+ cp .env.publish.example .env.publish
46
+ ```
47
+
48
+ Depois preencha `NPM_TOKEN` e rode:
49
+
50
+ ```sh
51
+ npm run release:cli -- patch
52
+ ```
package/dist/app.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export type AppProps = {
2
+ readonly appVersion: string;
3
+ readonly initialInput: string;
4
+ };
5
+ export declare function App({ appVersion, initialInput }: AppProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAaA,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B,CAAC;AAkGF,wBAAgB,GAAG,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,QAAQ,2CAyVzD"}
package/dist/app.js ADDED
@@ -0,0 +1,300 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text, useApp, useInput } from 'ink';
3
+ import { useEffect, useMemo, useState } from 'react';
4
+ import { DiscoveryPage } from './modules/discovery/page/discovery-page.js';
5
+ import { getUserDisplayName } from './modules/auth/auth-user.js';
6
+ import { getAuthBootstrapResult } from './modules/auth/auth-service.js';
7
+ import { LoginPage } from './modules/auth/page/login-page.js';
8
+ import { ProfilePage } from './modules/profile/page/profile-page.js';
9
+ import { ActionMenuPage } from './shared/components/action-menu-page.js';
10
+ import { AppMenu } from './shared/template/app-menu.js';
11
+ import { AppShell } from './shared/template/app-shell.js';
12
+ const MENU_ITEMS = [
13
+ {
14
+ id: 'discovery',
15
+ titulo: 'Descobrir Temas',
16
+ comando: 'discovery',
17
+ aliases: ['descobrir', 'Descobrir', 'temas', 'Temas'],
18
+ descricao: 'Inicia o fluxo de descoberta e coleta o tema da busca.',
19
+ palavrasChave: ['tema', 'Tema', 'descoberta', 'Descoberta', 'pesquisa', 'Pesquisa', 'amplo', 'restrito'],
20
+ },
21
+ {
22
+ id: 'profile',
23
+ titulo: 'Meu Perfil',
24
+ comando: 'profile',
25
+ aliases: ['perfil', 'Perfil', 'conta', 'Conta', 'usuário', 'usuario', 'Usuário', 'Usuario'],
26
+ descricao: 'Abre os fluxos de alteração de senha e display name.',
27
+ palavrasChave: [
28
+ 'senha',
29
+ 'Senha',
30
+ 'display name',
31
+ 'Display Name',
32
+ 'nome',
33
+ 'Nome',
34
+ 'usuário',
35
+ 'usuario',
36
+ 'Supabase',
37
+ 'supabase',
38
+ ],
39
+ },
40
+ {
41
+ id: 'logout',
42
+ titulo: 'Encerrar Sessão',
43
+ comando: 'logout',
44
+ aliases: ['sair-da-conta', 'sair da conta', 'Sair da Conta', 'deslogar', 'Deslogar'],
45
+ descricao: 'Remove a sessão salva localmente e volta para a tela de login.',
46
+ palavrasChave: ['auth', 'login', 'Login', 'conta', 'Conta', 'sessão', 'sessao', 'Sessão', 'Sessao', 'Supabase'],
47
+ },
48
+ {
49
+ id: 'exit',
50
+ titulo: 'Sair',
51
+ comando: 'sair',
52
+ aliases: ['exit', 'quit', 'sair', 'Sair'],
53
+ descricao: 'Sai do sistema sem perder a sessão do usuário ativa.',
54
+ palavrasChave: [
55
+ 'fechar',
56
+ 'Fechar',
57
+ 'encerrar',
58
+ 'Encerrar',
59
+ 'finalizar',
60
+ 'Finalizar',
61
+ 'sessão',
62
+ 'sessao',
63
+ 'usuário',
64
+ 'usuario',
65
+ ],
66
+ },
67
+ ];
68
+ const LOGOUT_OPTIONS = [
69
+ {
70
+ value: 'cancel',
71
+ label: 'Voltar ao menu',
72
+ description: 'Cancela a saida da conta e retorna para os comandos.',
73
+ },
74
+ {
75
+ value: 'confirm',
76
+ label: 'Encerrar sessao',
77
+ description: 'Remove a sessao local e exige novo login para continuar.',
78
+ },
79
+ ];
80
+ function formatScopeLabel(scope) {
81
+ return scope === 'amplo' ? 'mais ampla' : 'mais restrita';
82
+ }
83
+ function getAuthenticatedUserLabel(user) {
84
+ if (!user) {
85
+ return 'usuario autenticado';
86
+ }
87
+ return getUserDisplayName(user) ?? user.email ?? 'usuario autenticado';
88
+ }
89
+ function getWelcomeTitle(user) {
90
+ const displayName = user ? getUserDisplayName(user) : null;
91
+ if (displayName) {
92
+ return `Bem-vindo de volta, ${displayName}.`;
93
+ }
94
+ return 'Bem-vindo de volta.';
95
+ }
96
+ export function App({ appVersion, initialInput }) {
97
+ const { exit } = useApp();
98
+ const authBootstrap = useMemo(() => getAuthBootstrapResult(), []);
99
+ const authService = authBootstrap.ok ? authBootstrap.authService : null;
100
+ const sessionStorageFilePath = authService?.getSessionStorageFilePath() ?? '~/.trendify/auth/storage.json';
101
+ const [screen, setScreen] = useState('menu');
102
+ const [notification, setNotification] = useState(null);
103
+ const [notificationTone, setNotificationTone] = useState('success');
104
+ const [menuKey, setMenuKey] = useState(0);
105
+ const [authStatus, setAuthStatus] = useState(authBootstrap.ok ? 'booting' : 'config-error');
106
+ const [authUser, setAuthUser] = useState(null);
107
+ const [email, setEmail] = useState('');
108
+ const [password, setPassword] = useState('');
109
+ const [authBusy, setAuthBusy] = useState(false);
110
+ const [logoutSelectionIndex, setLogoutSelectionIndex] = useState(0);
111
+ useInput((input, key) => {
112
+ if (key.ctrl && input === 'c') {
113
+ exit();
114
+ }
115
+ });
116
+ useInput((_input, key) => {
117
+ if (screen !== 'confirm-logout' || authBusy) {
118
+ return;
119
+ }
120
+ if (key.escape) {
121
+ setScreen('menu');
122
+ setLogoutSelectionIndex(0);
123
+ return;
124
+ }
125
+ if (key.upArrow) {
126
+ setLogoutSelectionIndex((current) => (current === 0 ? LOGOUT_OPTIONS.length - 1 : current - 1));
127
+ return;
128
+ }
129
+ if (key.downArrow) {
130
+ setLogoutSelectionIndex((current) => (current === LOGOUT_OPTIONS.length - 1 ? 0 : current + 1));
131
+ return;
132
+ }
133
+ if (key.return) {
134
+ const option = LOGOUT_OPTIONS[logoutSelectionIndex];
135
+ if (option?.value === 'confirm') {
136
+ void handleLogout();
137
+ return;
138
+ }
139
+ setScreen('menu');
140
+ setLogoutSelectionIndex(0);
141
+ setNotification('Encerramento de sessao cancelado.');
142
+ setNotificationTone('info');
143
+ }
144
+ });
145
+ useEffect(() => {
146
+ if (!authService) {
147
+ return;
148
+ }
149
+ let active = true;
150
+ setAuthBusy(true);
151
+ const restoreSession = async () => {
152
+ const result = await authService.restoreSession();
153
+ if (!active) {
154
+ return;
155
+ }
156
+ if (result.error) {
157
+ setNotification(result.error);
158
+ setNotificationTone('error');
159
+ }
160
+ if (result.data?.user) {
161
+ setAuthStatus('authenticated');
162
+ setAuthUser(result.data.user);
163
+ }
164
+ else {
165
+ setAuthStatus('unauthenticated');
166
+ setAuthUser(null);
167
+ }
168
+ setAuthBusy(false);
169
+ };
170
+ void restoreSession();
171
+ const { data: { subscription }, } = authService.onAuthStateChange((snapshot) => {
172
+ if (!active) {
173
+ return;
174
+ }
175
+ if (snapshot.user) {
176
+ setAuthStatus('authenticated');
177
+ setAuthUser(snapshot.user);
178
+ setScreen((current) => (current === 'menu' || current === 'discovery' || current === 'profile' ? current : 'menu'));
179
+ return;
180
+ }
181
+ setAuthStatus('unauthenticated');
182
+ setAuthUser(null);
183
+ setScreen('menu');
184
+ setMenuKey((current) => current + 1);
185
+ });
186
+ return () => {
187
+ active = false;
188
+ subscription.unsubscribe();
189
+ };
190
+ }, [authService]);
191
+ async function handleLogin() {
192
+ if (!authService || authBusy) {
193
+ return;
194
+ }
195
+ const trimmedEmail = email.trim();
196
+ if (!trimmedEmail || !password.trim()) {
197
+ setNotification('Preencha email e senha para continuar.');
198
+ setNotificationTone('error');
199
+ return;
200
+ }
201
+ setAuthBusy(true);
202
+ setNotification(null);
203
+ const result = await authService.signInWithPassword(trimmedEmail, password);
204
+ setAuthBusy(false);
205
+ if (result.error || !result.data?.user) {
206
+ setPassword('');
207
+ setNotification(result.error ?? 'Nao foi possivel autenticar este usuario.');
208
+ setNotificationTone('error');
209
+ setAuthStatus('unauthenticated');
210
+ return;
211
+ }
212
+ setAuthStatus('authenticated');
213
+ setAuthUser(result.data.user);
214
+ setPassword('');
215
+ setNotification(`Sessao iniciada para ${result.data.user.email ?? trimmedEmail}.`);
216
+ setNotificationTone('success');
217
+ setScreen('menu');
218
+ setMenuKey((current) => current + 1);
219
+ }
220
+ async function handleLogout() {
221
+ if (!authService || authBusy) {
222
+ return;
223
+ }
224
+ setAuthBusy(true);
225
+ const result = await authService.signOut();
226
+ setAuthBusy(false);
227
+ if (result.error) {
228
+ setNotification(result.error);
229
+ setNotificationTone('error');
230
+ return;
231
+ }
232
+ setScreen('menu');
233
+ setEmail('');
234
+ setPassword('');
235
+ setMenuKey((current) => current + 1);
236
+ setLogoutSelectionIndex(0);
237
+ setNotification('Sessao local removida. Faca login novamente para continuar.');
238
+ setNotificationTone('success');
239
+ }
240
+ if (!authBootstrap.ok) {
241
+ return (_jsx(AppShell, { appVersion: appVersion, title: "Configuracao do Supabase pendente.", subtitle: "Defina as variaveis de ambiente antes de usar a CLI.", notification: authBootstrap.error, notificationTone: "error", children: _jsx(Text, { children: "Crie um arquivo .env com base em .env.example e preencha as chaves do projeto Supabase." }) }));
242
+ }
243
+ if (authStatus === 'booting') {
244
+ return (_jsx(AppShell, { appVersion: appVersion, title: "Validando sua sessao.", subtitle: "A CLI esta consultando o Supabase para restaurar uma sessao existente.", notification: notification, notificationTone: notificationTone, children: _jsx(Text, { dimColor: true, children: authBusy ? 'Aguarde alguns instantes...' : 'Pronto para autenticar.' }) }));
245
+ }
246
+ if (authStatus === 'unauthenticated') {
247
+ return (_jsx(AppShell, { appVersion: appVersion, title: "Login obrigatorio.", subtitle: "Somente usuarios ja cadastrados no Supabase podem usar a CLI.", notification: notification, notificationTone: notificationTone, children: _jsx(LoginPage, { busy: authBusy, email: email, password: password, sessionStorageFilePath: sessionStorageFilePath, onEmailChange: setEmail, onPasswordChange: setPassword, onSubmit: () => {
248
+ void handleLogin();
249
+ } }) }));
250
+ }
251
+ if (screen === 'discovery') {
252
+ return (_jsx(AppShell, { appVersion: appVersion, title: "Discovery", subtitle: `Sessao ativa para ${getAuthenticatedUserLabel(authUser)}.`, notification: notification, notificationTone: notificationTone, children: _jsx(DiscoveryPage, { onCancel: () => {
253
+ setScreen('menu');
254
+ setMenuKey((current) => current + 1);
255
+ }, onComplete: ({ theme, scope }) => {
256
+ setNotification(`Discovery finalizado: tema "${theme}" com abordagem ${formatScopeLabel(scope)}.`);
257
+ setNotificationTone('success');
258
+ setScreen('menu');
259
+ setMenuKey((current) => current + 1);
260
+ } }) }));
261
+ }
262
+ if (screen === 'profile' && authService && authUser) {
263
+ return (_jsx(AppShell, { appVersion: appVersion, title: "Profile", subtitle: `Sessao ativa para ${getAuthenticatedUserLabel(authUser)}.`, notification: notification, notificationTone: notificationTone, children: _jsx(ProfilePage, { authService: authService, user: authUser, onBack: () => {
264
+ setScreen('menu');
265
+ setMenuKey((current) => current + 1);
266
+ }, onNotificationChange: (nextNotification, nextTone = 'success') => {
267
+ setNotification(nextNotification);
268
+ setNotificationTone(nextTone);
269
+ } }) }));
270
+ }
271
+ if (screen === 'confirm-logout') {
272
+ return (_jsx(AppShell, { appVersion: appVersion, title: "Confirmar encerramento de sessao", subtitle: `Voce esta autenticado como ${getAuthenticatedUserLabel(authUser)}.`, notification: notification, notificationTone: notificationTone, children: _jsx(ActionMenuPage, { title: "Tem certeza que deseja encerrar a sessao atual?", subtitle: "Se confirmar, a CLI vai remover a sessao salva localmente e pedir login novamente.", options: LOGOUT_OPTIONS, selectedIndex: logoutSelectionIndex, hintText: "Use as setas para navegar. Enter confirma. Esc volta ao menu." }) }));
273
+ }
274
+ return (_jsx(AppShell, { appVersion: appVersion, title: getWelcomeTitle(authUser), subtitle: `Use a barra para abrir os comandos. Sessao ativa para ${getAuthenticatedUserLabel(authUser)}.`, notification: notification, notificationTone: notificationTone, children: _jsx(AppMenu, { initialInput: menuKey === 0 ? initialInput : '', items: MENU_ITEMS, onInputChange: () => {
275
+ if (notification) {
276
+ setNotification(null);
277
+ }
278
+ }, onSelect: (item) => {
279
+ if (item.id === 'logout') {
280
+ setNotification(null);
281
+ setNotificationTone('info');
282
+ setLogoutSelectionIndex(0);
283
+ setScreen('confirm-logout');
284
+ return;
285
+ }
286
+ if (item.id === 'profile') {
287
+ setNotification(null);
288
+ setNotificationTone('success');
289
+ setScreen('profile');
290
+ return;
291
+ }
292
+ if (item.id === 'exit') {
293
+ exit();
294
+ return;
295
+ }
296
+ setNotification(null);
297
+ setNotificationTone('success');
298
+ setScreen('discovery');
299
+ } }, menuKey) }));
300
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { render } from 'ink';
4
+ import { App } from './app.js';
5
+ import { APP_VERSION } from './version.js';
6
+ const args = process.argv.slice(2);
7
+ const initialInput = args
8
+ .filter((arg) => !arg.startsWith('-'))
9
+ .join(' ')
10
+ .trim();
11
+ if (args.includes('--help') || args.includes('-h')) {
12
+ process.stdout.write(`CLI
13
+
14
+ Uso:
15
+ trendify [opcoes]
16
+
17
+ Opcoes:
18
+ -h, --help Mostra esta ajuda
19
+ -v, --version Mostra a versao instalada
20
+ `);
21
+ process.exit(0);
22
+ }
23
+ if (args.includes('--version') || args.includes('-v')) {
24
+ process.stdout.write(`${APP_VERSION}\n`);
25
+ process.exit(0);
26
+ }
27
+ console.clear();
28
+ render(_jsx(App, { appVersion: APP_VERSION, initialInput: initialInput }));
@@ -0,0 +1,4 @@
1
+ export declare const TRENDIFY_HOME_DIR: string;
2
+ export declare const TRENDIFY_AUTH_DIR: string;
3
+ export declare const TRENDIFY_AUTH_STORAGE_FILE: string;
4
+ //# sourceMappingURL=app-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-paths.d.ts","sourceRoot":"","sources":["../../src/config/app-paths.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,QAA+B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAkC,CAAC;AACjE,eAAO,MAAM,0BAA0B,QAA0C,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { homedir } from 'node:os';
2
+ import { join } from 'node:path';
3
+ export const TRENDIFY_HOME_DIR = join(homedir(), '.trendify');
4
+ export const TRENDIFY_AUTH_DIR = join(TRENDIFY_HOME_DIR, 'auth');
5
+ export const TRENDIFY_AUTH_STORAGE_FILE = join(TRENDIFY_AUTH_DIR, 'storage.json');
@@ -0,0 +1,14 @@
1
+ export type CliEnv = {
2
+ readonly supabasePublishableDefaultKey: string;
3
+ readonly supabaseUrl: string;
4
+ };
5
+ export type EnvValidationResult = {
6
+ readonly ok: true;
7
+ readonly env: CliEnv;
8
+ } | {
9
+ readonly error: string;
10
+ readonly ok: false;
11
+ };
12
+ export declare function getCliEnvValidationResult(): EnvValidationResult;
13
+ export declare const CLI_APP_ROOT_DIRECTORY: string;
14
+ //# sourceMappingURL=env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/config/env.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,CAAC,6BAA6B,EAAE,MAAM,CAAC;IAC/C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAC3B;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,GACD;IACE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;CACpB,CAAC;AAsBN,wBAAgB,yBAAyB,IAAI,mBAAmB,CA+B/D;AAED,eAAO,MAAM,sBAAsB,QAAmB,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { config as loadEnv } from 'dotenv';
5
+ const currentFilePath = fileURLToPath(import.meta.url);
6
+ const currentDirectory = dirname(currentFilePath);
7
+ const appRootDirectory = resolve(currentDirectory, '..', '..');
8
+ const workspaceRootDirectory = resolve(appRootDirectory, '..', '..');
9
+ const ENV_FILE_PATHS = [
10
+ resolve(process.cwd(), '.env'),
11
+ resolve(appRootDirectory, '.env'),
12
+ resolve(workspaceRootDirectory, '.env'),
13
+ ];
14
+ let envLoaded = false;
15
+ function loadCliEnvFiles() {
16
+ if (envLoaded) {
17
+ return;
18
+ }
19
+ for (const envFilePath of ENV_FILE_PATHS) {
20
+ if (existsSync(envFilePath)) {
21
+ loadEnv({ override: false, path: envFilePath, quiet: true });
22
+ }
23
+ }
24
+ envLoaded = true;
25
+ }
26
+ function readEnvValue(name) {
27
+ const value = process.env[name]?.trim();
28
+ return value ? value : undefined;
29
+ }
30
+ export function getCliEnvValidationResult() {
31
+ loadCliEnvFiles();
32
+ const supabaseUrl = readEnvValue('SUPABASE_URL');
33
+ const supabasePublishableDefaultKey = readEnvValue('SUPABASE_PUBLISHABLE_DEFAULT_KEY');
34
+ const missingVariables = [
35
+ !supabaseUrl ? 'SUPABASE_URL' : null,
36
+ !supabasePublishableDefaultKey ? 'SUPABASE_PUBLISHABLE_DEFAULT_KEY' : null,
37
+ ].filter((value) => Boolean(value));
38
+ if (missingVariables.length > 0) {
39
+ return {
40
+ ok: false,
41
+ error: `Defina ${missingVariables.join(' e ')} antes de iniciar a CLI.`,
42
+ };
43
+ }
44
+ if (!supabaseUrl || !supabasePublishableDefaultKey) {
45
+ return {
46
+ ok: false,
47
+ error: 'Nao foi possivel validar as variaveis do Supabase.',
48
+ };
49
+ }
50
+ return {
51
+ ok: true,
52
+ env: {
53
+ supabaseUrl,
54
+ supabasePublishableDefaultKey,
55
+ },
56
+ };
57
+ }
58
+ export const CLI_APP_ROOT_DIRECTORY = appRootDirectory;
@@ -0,0 +1,39 @@
1
+ import { type AuthSession, type AuthUser } from '@supabase/supabase-js';
2
+ import { type CliEnv } from '../../config/env.js';
3
+ export type AuthSnapshot = {
4
+ readonly session: AuthSession | null;
5
+ readonly user: AuthUser | null;
6
+ };
7
+ export type AuthActionResult<TData> = {
8
+ readonly data: TData | null;
9
+ readonly error: string | null;
10
+ readonly errorCode: string | null;
11
+ };
12
+ export type AuthBootstrapResult = {
13
+ readonly authService: AuthService;
14
+ readonly env: CliEnv;
15
+ readonly ok: true;
16
+ } | {
17
+ readonly error: string;
18
+ readonly ok: false;
19
+ };
20
+ export declare class AuthService {
21
+ private readonly client;
22
+ private readonly storageFilePath;
23
+ static create(env: CliEnv): AuthService;
24
+ private constructor();
25
+ getSessionStorageFilePath(): string;
26
+ onAuthStateChange(listener: (snapshot: AuthSnapshot) => void): {
27
+ data: {
28
+ subscription: import("@supabase/supabase-js").Subscription;
29
+ };
30
+ };
31
+ restoreSession(): Promise<AuthActionResult<AuthSnapshot>>;
32
+ signInWithPassword(email: string, password: string): Promise<AuthActionResult<AuthSnapshot>>;
33
+ signOut(): Promise<AuthActionResult<null>>;
34
+ updateDisplayName(displayName: string): Promise<AuthActionResult<AuthUser>>;
35
+ sendPasswordReauthenticationCode(): Promise<AuthActionResult<null>>;
36
+ updatePassword(password: string, nonce?: string): Promise<AuthActionResult<AuthUser>>;
37
+ }
38
+ export declare function getAuthBootstrapResult(): AuthBootstrapResult;
39
+ //# sourceMappingURL=auth-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-service.d.ts","sourceRoot":"","sources":["../../../src/modules/auth/auth-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,QAAQ,EAEd,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAA6B,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAK7E,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,KAAK,IAChC;IACE,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,CAAC;AAEJ,MAAM,MAAM,mBAAmB,GAC3B;IACE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;CACnB,GACD;IACE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;CACpB,CAAC;AAUN,qBAAa,WAAW;IAiBpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe;WAjBpB,MAAM,CAAC,GAAG,EAAE,MAAM;IAehC,OAAO;IAKA,yBAAyB,IAAI,MAAM;IAInC,iBAAiB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI;;;;;IAStD,cAAc,IAAI,OAAO,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IA6DzD,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAwC5F,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IA0B1C,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAmE3E,gCAAgC,IAAI,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IA0BnE,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;CA0CnG;AAID,wBAAgB,sBAAsB,IAAI,mBAAmB,CAoB5D"}