@portaidentity/cli 1.7.3 → 1.8.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/CHANGELOG.md +5 -0
- package/README.md +125 -105
- package/dist/admin/admin-date-time.d.ts +6 -0
- package/dist/admin/admin-date-time.d.ts.map +1 -0
- package/dist/admin/admin-date-time.js +33 -0
- package/dist/admin/admin-date-time.js.map +1 -0
- package/dist/admin/application-client-features.d.ts +38 -0
- package/dist/admin/application-client-features.d.ts.map +1 -0
- package/dist/admin/application-client-features.js +545 -0
- package/dist/admin/application-client-features.js.map +1 -0
- package/dist/admin/application-controller.d.ts +58 -0
- package/dist/admin/application-controller.d.ts.map +1 -0
- package/dist/admin/application-controller.js +286 -0
- package/dist/admin/application-controller.js.map +1 -0
- package/dist/admin/application-dialogs.d.ts +91 -0
- package/dist/admin/application-dialogs.d.ts.map +1 -0
- package/dist/admin/application-dialogs.js +250 -0
- package/dist/admin/application-dialogs.js.map +1 -0
- package/dist/admin/application-rbac-controller.d.ts +56 -0
- package/dist/admin/application-rbac-controller.d.ts.map +1 -0
- package/dist/admin/application-rbac-controller.js +280 -0
- package/dist/admin/application-rbac-controller.js.map +1 -0
- package/dist/admin/application-rbac-features.d.ts +51 -0
- package/dist/admin/application-rbac-features.d.ts.map +1 -0
- package/dist/admin/application-rbac-features.js +175 -0
- package/dist/admin/application-rbac-features.js.map +1 -0
- package/dist/admin/application-rbac-workspace.d.ts +62 -0
- package/dist/admin/application-rbac-workspace.d.ts.map +1 -0
- package/dist/admin/application-rbac-workspace.js +344 -0
- package/dist/admin/application-rbac-workspace.js.map +1 -0
- package/dist/admin/application-runtime.d.ts +44 -0
- package/dist/admin/application-runtime.d.ts.map +1 -0
- package/dist/admin/application-runtime.js +183 -0
- package/dist/admin/application-runtime.js.map +1 -0
- package/dist/admin/application-service.d.ts +39 -0
- package/dist/admin/application-service.d.ts.map +1 -0
- package/dist/admin/application-service.js +248 -0
- package/dist/admin/application-service.js.map +1 -0
- package/dist/admin/application-state.d.ts +109 -0
- package/dist/admin/application-state.d.ts.map +1 -0
- package/dist/admin/application-state.js +3 -0
- package/dist/admin/application-state.js.map +1 -0
- package/dist/admin/application-workspace.d.ts +77 -0
- package/dist/admin/application-workspace.d.ts.map +1 -0
- package/dist/admin/application-workspace.js +302 -0
- package/dist/admin/application-workspace.js.map +1 -0
- package/dist/admin/application.d.ts +88 -0
- package/dist/admin/application.d.ts.map +1 -0
- package/dist/admin/application.js +932 -0
- package/dist/admin/application.js.map +1 -0
- package/dist/admin/client-authentication-dialog.d.ts +77 -0
- package/dist/admin/client-authentication-dialog.d.ts.map +1 -0
- package/dist/admin/client-authentication-dialog.js +217 -0
- package/dist/admin/client-authentication-dialog.js.map +1 -0
- package/dist/admin/client-controller.d.ts +58 -0
- package/dist/admin/client-controller.d.ts.map +1 -0
- package/dist/admin/client-controller.js +462 -0
- package/dist/admin/client-controller.js.map +1 -0
- package/dist/admin/client-credential-dialogs.d.ts +36 -0
- package/dist/admin/client-credential-dialogs.d.ts.map +1 -0
- package/dist/admin/client-credential-dialogs.js +145 -0
- package/dist/admin/client-credential-dialogs.js.map +1 -0
- package/dist/admin/client-dialogs.d.ts +64 -0
- package/dist/admin/client-dialogs.d.ts.map +1 -0
- package/dist/admin/client-dialogs.js +110 -0
- package/dist/admin/client-dialogs.js.map +1 -0
- package/dist/admin/client-form-scroller.d.ts +17 -0
- package/dist/admin/client-form-scroller.d.ts.map +1 -0
- package/dist/admin/client-form-scroller.js +67 -0
- package/dist/admin/client-form-scroller.js.map +1 -0
- package/dist/admin/client-registration-dialog.d.ts +27 -0
- package/dist/admin/client-registration-dialog.d.ts.map +1 -0
- package/dist/admin/client-registration-dialog.js +195 -0
- package/dist/admin/client-registration-dialog.js.map +1 -0
- package/dist/admin/client-service.d.ts +41 -0
- package/dist/admin/client-service.d.ts.map +1 -0
- package/dist/admin/client-service.js +484 -0
- package/dist/admin/client-service.js.map +1 -0
- package/dist/admin/client-state.d.ts +157 -0
- package/dist/admin/client-state.d.ts.map +1 -0
- package/dist/admin/client-state.js +3 -0
- package/dist/admin/client-state.js.map +1 -0
- package/dist/admin/client-workspace.d.ts +88 -0
- package/dist/admin/client-workspace.d.ts.map +1 -0
- package/dist/admin/client-workspace.js +484 -0
- package/dist/admin/client-workspace.js.map +1 -0
- package/dist/admin/delete-confirmation-layout.d.ts +38 -0
- package/dist/admin/delete-confirmation-layout.d.ts.map +1 -0
- package/dist/admin/delete-confirmation-layout.js +52 -0
- package/dist/admin/delete-confirmation-layout.js.map +1 -0
- package/dist/admin/index.d.ts +64 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +31 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/organization-controller.d.ts +77 -0
- package/dist/admin/organization-controller.d.ts.map +1 -0
- package/dist/admin/organization-controller.js +472 -0
- package/dist/admin/organization-controller.js.map +1 -0
- package/dist/admin/organization-dialogs.d.ts +63 -0
- package/dist/admin/organization-dialogs.d.ts.map +1 -0
- package/dist/admin/organization-dialogs.js +303 -0
- package/dist/admin/organization-dialogs.js.map +1 -0
- package/dist/admin/organization-service.d.ts +110 -0
- package/dist/admin/organization-service.d.ts.map +1 -0
- package/dist/admin/organization-service.js +548 -0
- package/dist/admin/organization-service.js.map +1 -0
- package/dist/admin/organization-workspace.d.ts +29 -0
- package/dist/admin/organization-workspace.d.ts.map +1 -0
- package/dist/admin/organization-workspace.js +421 -0
- package/dist/admin/organization-workspace.js.map +1 -0
- package/dist/admin/portability-controller.d.ts +83 -0
- package/dist/admin/portability-controller.d.ts.map +1 -0
- package/dist/admin/portability-controller.js +466 -0
- package/dist/admin/portability-controller.js.map +1 -0
- package/dist/admin/portability-service.d.ts +31 -0
- package/dist/admin/portability-service.d.ts.map +1 -0
- package/dist/admin/portability-service.js +51 -0
- package/dist/admin/portability-service.js.map +1 -0
- package/dist/admin/portability-state.d.ts +88 -0
- package/dist/admin/portability-state.d.ts.map +1 -0
- package/dist/admin/portability-state.js +3 -0
- package/dist/admin/portability-state.js.map +1 -0
- package/dist/admin/portability-workspace.d.ts +78 -0
- package/dist/admin/portability-workspace.d.ts.map +1 -0
- package/dist/admin/portability-workspace.js +337 -0
- package/dist/admin/portability-workspace.js.map +1 -0
- package/dist/admin/presentation.d.ts +46 -0
- package/dist/admin/presentation.d.ts.map +1 -0
- package/dist/admin/presentation.js +271 -0
- package/dist/admin/presentation.js.map +1 -0
- package/dist/admin/rbac-dialogs.d.ts +73 -0
- package/dist/admin/rbac-dialogs.d.ts.map +1 -0
- package/dist/admin/rbac-dialogs.js +345 -0
- package/dist/admin/rbac-dialogs.js.map +1 -0
- package/dist/admin/rbac-service.d.ts +47 -0
- package/dist/admin/rbac-service.d.ts.map +1 -0
- package/dist/admin/rbac-service.js +258 -0
- package/dist/admin/rbac-service.js.map +1 -0
- package/dist/admin/rbac-state.d.ts +129 -0
- package/dist/admin/rbac-state.d.ts.map +1 -0
- package/dist/admin/rbac-state.js +136 -0
- package/dist/admin/rbac-state.js.map +1 -0
- package/dist/admin/selectable-read-only-input.d.ts +18 -0
- package/dist/admin/selectable-read-only-input.d.ts.map +1 -0
- package/dist/admin/selectable-read-only-input.js +24 -0
- package/dist/admin/selectable-read-only-input.js.map +1 -0
- package/dist/admin/session-service.d.ts +169 -0
- package/dist/admin/session-service.d.ts.map +1 -0
- package/dist/admin/session-service.js +353 -0
- package/dist/admin/session-service.js.map +1 -0
- package/dist/admin/state.d.ts +301 -0
- package/dist/admin/state.d.ts.map +1 -0
- package/dist/admin/state.js +10 -0
- package/dist/admin/state.js.map +1 -0
- package/dist/admin/system-config-controller.d.ts +58 -0
- package/dist/admin/system-config-controller.d.ts.map +1 -0
- package/dist/admin/system-config-controller.js +218 -0
- package/dist/admin/system-config-controller.js.map +1 -0
- package/dist/admin/system-config-service.d.ts +54 -0
- package/dist/admin/system-config-service.d.ts.map +1 -0
- package/dist/admin/system-config-service.js +180 -0
- package/dist/admin/system-config-service.js.map +1 -0
- package/dist/admin/system-config-state.d.ts +77 -0
- package/dist/admin/system-config-state.d.ts.map +1 -0
- package/dist/admin/system-config-state.js +78 -0
- package/dist/admin/system-config-state.js.map +1 -0
- package/dist/admin/system-config-workspace.d.ts +47 -0
- package/dist/admin/system-config-workspace.d.ts.map +1 -0
- package/dist/admin/system-config-workspace.js +217 -0
- package/dist/admin/system-config-workspace.js.map +1 -0
- package/dist/admin/user-controller-types.d.ts +67 -0
- package/dist/admin/user-controller-types.d.ts.map +1 -0
- package/dist/admin/user-controller-types.js +3 -0
- package/dist/admin/user-controller-types.js.map +1 -0
- package/dist/admin/user-controller.d.ts +6 -0
- package/dist/admin/user-controller.d.ts.map +1 -0
- package/dist/admin/user-controller.js +674 -0
- package/dist/admin/user-controller.js.map +1 -0
- package/dist/admin/user-dialog-fields.d.ts +44 -0
- package/dist/admin/user-dialog-fields.d.ts.map +1 -0
- package/dist/admin/user-dialog-fields.js +130 -0
- package/dist/admin/user-dialog-fields.js.map +1 -0
- package/dist/admin/user-dialogs.d.ts +66 -0
- package/dist/admin/user-dialogs.d.ts.map +1 -0
- package/dist/admin/user-dialogs.js +374 -0
- package/dist/admin/user-dialogs.js.map +1 -0
- package/dist/admin/user-role-controller.d.ts +82 -0
- package/dist/admin/user-role-controller.d.ts.map +1 -0
- package/dist/admin/user-role-controller.js +337 -0
- package/dist/admin/user-role-controller.js.map +1 -0
- package/dist/admin/user-role-dialog.d.ts +94 -0
- package/dist/admin/user-role-dialog.d.ts.map +1 -0
- package/dist/admin/user-role-dialog.js +265 -0
- package/dist/admin/user-role-dialog.js.map +1 -0
- package/dist/admin/user-service-types.d.ts +100 -0
- package/dist/admin/user-service-types.d.ts.map +1 -0
- package/dist/admin/user-service-types.js +3 -0
- package/dist/admin/user-service-types.js.map +1 -0
- package/dist/admin/user-service.d.ts +14 -0
- package/dist/admin/user-service.d.ts.map +1 -0
- package/dist/admin/user-service.js +612 -0
- package/dist/admin/user-service.js.map +1 -0
- package/dist/admin/user-state.d.ts +158 -0
- package/dist/admin/user-state.d.ts.map +1 -0
- package/dist/admin/user-state.js +3 -0
- package/dist/admin/user-state.js.map +1 -0
- package/dist/admin/user-workspace.d.ts +65 -0
- package/dist/admin/user-workspace.d.ts.map +1 -0
- package/dist/admin/user-workspace.js +366 -0
- package/dist/admin/user-workspace.js.map +1 -0
- package/dist/auth/browser-flow.d.ts +27 -1
- package/dist/auth/browser-flow.d.ts.map +1 -1
- package/dist/auth/browser-flow.js +55 -33
- package/dist/auth/browser-flow.js.map +1 -1
- package/dist/auth/callback-server.d.ts.map +1 -1
- package/dist/auth/callback-server.js +5 -9
- package/dist/auth/callback-server.js.map +1 -1
- package/dist/auth/id-token-verifier.d.ts +39 -0
- package/dist/auth/id-token-verifier.d.ts.map +1 -0
- package/dist/auth/id-token-verifier.js +104 -0
- package/dist/auth/id-token-verifier.js.map +1 -0
- package/dist/auth/login-coordinator.d.ts +72 -0
- package/dist/auth/login-coordinator.d.ts.map +1 -0
- package/dist/auth/login-coordinator.js +190 -0
- package/dist/auth/login-coordinator.js.map +1 -0
- package/dist/auth/metadata.d.ts +2 -1
- package/dist/auth/metadata.d.ts.map +1 -1
- package/dist/auth/metadata.js +67 -6
- package/dist/auth/metadata.js.map +1 -1
- package/dist/auth/types.d.ts +14 -0
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/client-factory.d.ts.map +1 -1
- package/dist/client-factory.js +15 -2
- package/dist/client-factory.js.map +1 -1
- package/dist/commands/admin.d.ts +22 -0
- package/dist/commands/admin.d.ts.map +1 -0
- package/dist/commands/admin.js +112 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/app-claim.d.ts.map +1 -1
- package/dist/commands/app-claim.js +11 -4
- package/dist/commands/app-claim.js.map +1 -1
- package/dist/commands/app-module.d.ts.map +1 -1
- package/dist/commands/app-module.js +61 -12
- package/dist/commands/app-module.js.map +1 -1
- package/dist/commands/app-permission.d.ts.map +1 -1
- package/dist/commands/app-permission.js +66 -24
- package/dist/commands/app-permission.js.map +1 -1
- package/dist/commands/app-role.d.ts.map +1 -1
- package/dist/commands/app-role.js +48 -27
- package/dist/commands/app-role.js.map +1 -1
- package/dist/commands/app.d.ts.map +1 -1
- package/dist/commands/app.js +37 -25
- package/dist/commands/app.js.map +1 -1
- package/dist/commands/bulk.d.ts.map +1 -1
- package/dist/commands/bulk.js +9 -2
- package/dist/commands/bulk.js.map +1 -1
- package/dist/commands/client-secret.d.ts.map +1 -1
- package/dist/commands/client-secret.js +12 -6
- package/dist/commands/client-secret.js.map +1 -1
- package/dist/commands/client.d.ts +3 -2
- package/dist/commands/client.d.ts.map +1 -1
- package/dist/commands/client.js +87 -43
- package/dist/commands/client.js.map +1 -1
- package/dist/commands/config.d.ts +4 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +68 -7
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/export.d.ts +6 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +182 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/import.d.ts +6 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +142 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/keys.d.ts.map +1 -1
- package/dist/commands/keys.js +11 -4
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +24 -10
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/org.d.ts +2 -4
- package/dist/commands/org.d.ts.map +1 -1
- package/dist/commands/org.js +16 -76
- package/dist/commands/org.js.map +1 -1
- package/dist/commands/user-role.d.ts.map +1 -1
- package/dist/commands/user-role.js +19 -14
- package/dist/commands/user-role.js.map +1 -1
- package/dist/commands/user.d.ts +3 -2
- package/dist/commands/user.d.ts.map +1 -1
- package/dist/commands/user.js +47 -71
- package/dist/commands/user.js.map +1 -1
- package/dist/commands/version.d.ts +1 -1
- package/dist/commands/version.js +1 -1
- package/dist/credential-lock.d.ts +20 -0
- package/dist/credential-lock.d.ts.map +1 -0
- package/dist/credential-lock.js +130 -0
- package/dist/credential-lock.js.map +1 -0
- package/dist/credential-store.d.ts +14 -0
- package/dist/credential-store.d.ts.map +1 -1
- package/dist/credential-store.js +114 -3
- package/dist/credential-store.js.map +1 -1
- package/dist/error-handler.d.ts.map +1 -1
- package/dist/error-handler.js +2 -0
- package/dist/error-handler.js.map +1 -1
- package/dist/global-options.d.ts +8 -0
- package/dist/global-options.d.ts.map +1 -1
- package/dist/global-options.js +19 -8
- package/dist/global-options.js.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/output.d.ts +11 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +25 -6
- package/dist/output.js.map +1 -1
- package/dist/prompt.d.ts +2 -2
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +27 -7
- package/dist/prompt.js.map +1 -1
- package/package.json +7 -3
- package/dist/commands/gui.d.ts +0 -21
- package/dist/commands/gui.d.ts.map +0 -1
- package/dist/commands/gui.js +0 -67
- package/dist/commands/gui.js.map +0 -1
- package/dist/commands/provision.d.ts +0 -47
- package/dist/commands/provision.d.ts.map +0 -1
- package/dist/commands/provision.js +0 -444
- package/dist/commands/provision.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.8.0] - 2026-09-23
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Version bump to 1.8.0
|
|
12
|
+
|
|
8
13
|
## [1.7.3] - 2026-08-26
|
|
9
14
|
|
|
10
15
|
### Changed
|
package/README.md
CHANGED
|
@@ -4,9 +4,9 @@ The official command-line interface for the [Porta Identity Platform](https://gi
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
7
|
+
- **28 command modules** — Full admin coverage: orgs, apps, clients, users, roles, permissions, claims, secrets, sessions, audit, and more
|
|
8
8
|
- **OIDC authentication** — Secure login via Authorization Code + PKCE (opens your browser, no passwords stored)
|
|
9
|
-
- **
|
|
9
|
+
- **Selective portability** — Export and import strict JSON manifests with preview-first application
|
|
10
10
|
- **Built on `@portaidentity/sdk`** — Type-safe API calls with automatic error handling
|
|
11
11
|
- **JSON output mode** — Machine-readable output for scripting and CI/CD (`--json`)
|
|
12
12
|
- **Shell completions** — Tab completion for Bash, Zsh, and Fish
|
|
@@ -60,36 +60,36 @@ Every command supports these flags:
|
|
|
60
60
|
|
|
61
61
|
### Authentication
|
|
62
62
|
|
|
63
|
-
| Command | Description
|
|
64
|
-
| -------------- |
|
|
65
|
-
| `porta login` | Authenticate via OIDC (Auth Code + PKCE) — opens browser
|
|
66
|
-
| `porta logout` | Clear stored credentials
|
|
67
|
-
| `porta whoami` | Display current identity (no network call)
|
|
63
|
+
| Command | Description |
|
|
64
|
+
| -------------- | --------------------------------------------------------------- |
|
|
65
|
+
| `porta login` | Authenticate via OIDC (Auth Code + PKCE) — opens browser |
|
|
66
|
+
| `porta logout` | Clear stored credentials |
|
|
67
|
+
| `porta whoami` | Display current identity (no network call) |
|
|
68
|
+
| `porta admin` | Open the interactive organization and user administration shell |
|
|
68
69
|
|
|
69
70
|
### Organizations
|
|
70
71
|
|
|
71
|
-
| Command
|
|
72
|
-
|
|
|
73
|
-
| `porta org list`
|
|
74
|
-
| `porta org create`
|
|
75
|
-
| `porta org show <id>`
|
|
76
|
-
| `porta org update <id>`
|
|
77
|
-
| `porta org activate <id>`
|
|
78
|
-
| `porta org suspend <id>`
|
|
79
|
-
| `porta org
|
|
80
|
-
| `porta org destroy <slug>` | Permanently delete an organization and all child entities |
|
|
72
|
+
| Command | Description |
|
|
73
|
+
| ------------------------- | ----------------------------------------------------- |
|
|
74
|
+
| `porta org list` | List all organizations |
|
|
75
|
+
| `porta org create` | Create a new organization |
|
|
76
|
+
| `porta org show <id>` | Show organization details |
|
|
77
|
+
| `porta org update <id>` | Update organization properties |
|
|
78
|
+
| `porta org activate <id>` | Activate an organization |
|
|
79
|
+
| `porta org suspend <id>` | Suspend an organization |
|
|
80
|
+
| `porta org delete <id>` | Permanently delete an organization and its owned data |
|
|
81
81
|
|
|
82
82
|
### Applications
|
|
83
83
|
|
|
84
|
-
| Command | Description
|
|
85
|
-
| ------------------------- |
|
|
86
|
-
| `porta app list` | List applications
|
|
87
|
-
| `porta app create` | Create a new application
|
|
88
|
-
| `porta app show <id>` | Show application details
|
|
89
|
-
| `porta app update <id>` | Update application properties
|
|
90
|
-
| `porta app activate <id>` | Activate an application
|
|
91
|
-
| `porta app suspend <id>` | Suspend an application
|
|
92
|
-
| `porta app
|
|
84
|
+
| Command | Description |
|
|
85
|
+
| ------------------------- | ---------------------------------------------------- |
|
|
86
|
+
| `porta app list` | List applications |
|
|
87
|
+
| `porta app create` | Create a new application |
|
|
88
|
+
| `porta app show <id>` | Show application details |
|
|
89
|
+
| `porta app update <id>` | Update application properties |
|
|
90
|
+
| `porta app activate <id>` | Activate an application |
|
|
91
|
+
| `porta app suspend <id>` | Suspend an application |
|
|
92
|
+
| `porta app delete <id>` | Permanently delete an application and its owned data |
|
|
93
93
|
|
|
94
94
|
**Nested: Roles** (`porta app role ...`)
|
|
95
95
|
|
|
@@ -99,51 +99,57 @@ Every command supports these flags:
|
|
|
99
99
|
| `porta app role list <app-id>` | List roles |
|
|
100
100
|
| `porta app role show <app-id> <role-id>` | Show role details |
|
|
101
101
|
| `porta app role update <app-id> <role-id>` | Update a role |
|
|
102
|
-
| `porta app role
|
|
102
|
+
| `porta app role delete <app-id> <role-id>` | Permanently delete a role |
|
|
103
103
|
| `porta app role assign-perm <app-id> <role-id> <perm-id>` | Assign permission to role |
|
|
104
104
|
| `porta app role remove-perm <app-id> <role-id> <perm-id>` | Remove permission from role |
|
|
105
105
|
|
|
106
106
|
**Nested: Permissions** (`porta app permission ...`)
|
|
107
107
|
|
|
108
|
-
| Command
|
|
109
|
-
|
|
|
110
|
-
| `porta app permission create <app-id>`
|
|
111
|
-
| `porta app permission list <app-id>`
|
|
112
|
-
| `porta app permission show <app-id> <perm-id>`
|
|
113
|
-
| `porta app permission
|
|
108
|
+
| Command | Description |
|
|
109
|
+
| ------------------------------------------------ | ------------------------------- |
|
|
110
|
+
| `porta app permission create <app-id>` | Create a permission |
|
|
111
|
+
| `porta app permission list <app-id>` | List permissions |
|
|
112
|
+
| `porta app permission show <app-id> <perm-id>` | Show permission details |
|
|
113
|
+
| `porta app permission delete <app-id> <perm-id>` | Permanently delete a permission |
|
|
114
114
|
|
|
115
115
|
**Nested: Claims** (`porta app claim ...`)
|
|
116
116
|
|
|
117
|
-
| Command
|
|
118
|
-
|
|
|
119
|
-
| `porta app claim create <app-id>`
|
|
120
|
-
| `porta app claim list <app-id>`
|
|
121
|
-
| `porta app claim show <app-id> <claim-id>`
|
|
122
|
-
| `porta app claim update <app-id> <claim-id>`
|
|
123
|
-
| `porta app claim
|
|
117
|
+
| Command | Description |
|
|
118
|
+
| -------------------------------------------- | ------------------------------------- |
|
|
119
|
+
| `porta app claim create <app-id>` | Create a claim definition |
|
|
120
|
+
| `porta app claim list <app-id>` | List claim definitions |
|
|
121
|
+
| `porta app claim show <app-id> <claim-id>` | Show claim details |
|
|
122
|
+
| `porta app claim update <app-id> <claim-id>` | Update a claim definition |
|
|
123
|
+
| `porta app claim delete <app-id> <claim-id>` | Permanently delete a claim definition |
|
|
124
124
|
|
|
125
125
|
**Nested: Modules** (`porta app module ...`)
|
|
126
126
|
|
|
127
|
-
| Command
|
|
128
|
-
|
|
|
129
|
-
| `porta app module list <app-id>`
|
|
130
|
-
| `porta app module enable <app-id>`
|
|
131
|
-
| `porta app module disable <app-id>`
|
|
127
|
+
| Command | Description |
|
|
128
|
+
| ---------------------------------------------- | ----------------------------------------------- |
|
|
129
|
+
| `porta app module list <app-id>` | List application modules |
|
|
130
|
+
| `porta app module enable <app-id>` | Enable a module |
|
|
131
|
+
| `porta app module disable <app-id>` | Disable a module |
|
|
132
|
+
| `porta app module delete <app-id> <module-id>` | Permanently delete a module and its permissions |
|
|
132
133
|
|
|
133
134
|
### Clients
|
|
134
135
|
|
|
135
|
-
| Command
|
|
136
|
-
|
|
|
137
|
-
| `porta client list`
|
|
138
|
-
| `porta client create`
|
|
139
|
-
| `porta client show <id>`
|
|
140
|
-
| `porta client update <id>`
|
|
141
|
-
| `porta client activate <id>`
|
|
142
|
-
| `porta client
|
|
143
|
-
| `porta client
|
|
136
|
+
| Command | Description |
|
|
137
|
+
| ------------------------------ | ------------------------------- |
|
|
138
|
+
| `porta client list` | List clients |
|
|
139
|
+
| `porta client create` | Create a new client |
|
|
140
|
+
| `porta client show <id>` | Show client details |
|
|
141
|
+
| `porta client update <id>` | Update client properties |
|
|
142
|
+
| `porta client activate <id>` | Activate a client |
|
|
143
|
+
| `porta client deactivate <id>` | Temporarily deactivate a client |
|
|
144
|
+
| `porta client delete <id>` | Permanently delete a client |
|
|
144
145
|
|
|
145
146
|
**Nested: Secrets** (`porta client secret ...`)
|
|
146
147
|
|
|
148
|
+
The interactive `porta admin` client workspace uses focused Overview, Authentication, Protocol,
|
|
149
|
+
Login experience, Credentials, and Lifecycle sections. Multi-field editors fill the Admin surface;
|
|
150
|
+
secret generation supports 3, 6, 12, and 24 month presets, a custom calendar date, or Never. Secret
|
|
151
|
+
plaintext is shown once and is never retained in the workspace.
|
|
152
|
+
|
|
147
153
|
| Command | Description |
|
|
148
154
|
| ---------------------------------------------------- | ---------------------------- |
|
|
149
155
|
| `porta client secret create <client-id>` | Generate a new client secret |
|
|
@@ -152,16 +158,16 @@ Every command supports these flags:
|
|
|
152
158
|
|
|
153
159
|
### Users
|
|
154
160
|
|
|
155
|
-
| Command
|
|
156
|
-
|
|
|
157
|
-
| `porta user list <org-id>`
|
|
158
|
-
| `porta user create <org-id>`
|
|
159
|
-
| `porta user show <org-id> <user-id>`
|
|
160
|
-
| `porta user update <org-id> <user-id>`
|
|
161
|
-
| `porta user invite <org-id>`
|
|
162
|
-
| `porta user
|
|
163
|
-
| `porta user
|
|
164
|
-
| `porta user
|
|
161
|
+
| Command | Description |
|
|
162
|
+
| ------------------------------------------ | ----------------------------- |
|
|
163
|
+
| `porta user list <org-id>` | List users in an organization |
|
|
164
|
+
| `porta user create <org-id>` | Create a new user |
|
|
165
|
+
| `porta user show <org-id> <user-id>` | Show user details |
|
|
166
|
+
| `porta user update <org-id> <user-id>` | Update user properties |
|
|
167
|
+
| `porta user invite <org-id>` | Send a user invitation |
|
|
168
|
+
| `porta user deactivate <org-id> <user-id>` | Deactivate a user |
|
|
169
|
+
| `porta user activate <org-id> <user-id>` | Activate a user |
|
|
170
|
+
| `porta user delete <org-id> <user-id>` | Permanently delete a user |
|
|
165
171
|
|
|
166
172
|
**Nested: Roles** (`porta user role ...`)
|
|
167
173
|
|
|
@@ -196,15 +202,18 @@ Every command supports these flags:
|
|
|
196
202
|
| `porta health` | Check server connectivity (no auth required) |
|
|
197
203
|
| `porta bulk <action>` | Bulk status operations on orgs/users |
|
|
198
204
|
| `porta exports download --entity-type <type>` | Export bounded allowlisted data as CSV or JSON |
|
|
205
|
+
| `porta export manifest ...` | Export a selective portability manifest |
|
|
206
|
+
| `porta import manifest <path> --mode <mode>` | Preview and import a portability manifest |
|
|
199
207
|
|
|
200
|
-
###
|
|
208
|
+
### Environment Portability
|
|
201
209
|
|
|
202
|
-
| Command
|
|
203
|
-
|
|
|
204
|
-
| `porta
|
|
210
|
+
| Command | Description |
|
|
211
|
+
| -------------------------------------------- | ------------------------------------------------ |
|
|
212
|
+
| `porta export manifest` | Export selected categories to a strict JSON file |
|
|
213
|
+
| `porta import manifest <path> --mode <mode>` | Preview, confirm, and apply a strict JSON file |
|
|
205
214
|
|
|
206
|
-
|
|
207
|
-
|
|
215
|
+
Import modes are `keep-existing` and `update-existing`. Both flows support `--json`; `--yes`
|
|
216
|
+
skips only the relevant file-replacement or apply confirmation.
|
|
208
217
|
|
|
209
218
|
### Utilities
|
|
210
219
|
|
|
@@ -233,46 +242,57 @@ porta login --server https://porta.example.com
|
|
|
233
242
|
porta login --server https://porta.example.com --no-browser
|
|
234
243
|
```
|
|
235
244
|
|
|
236
|
-
##
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
```yaml
|
|
241
|
-
# provision.yaml
|
|
242
|
-
organizations:
|
|
243
|
-
- name: Acme Corp
|
|
244
|
-
slug: acme
|
|
245
|
-
status: active
|
|
246
|
-
applications:
|
|
247
|
-
- name: Web Portal
|
|
248
|
-
slug: web-portal
|
|
249
|
-
clients:
|
|
250
|
-
- name: web-app
|
|
251
|
-
grant_types: [authorization_code]
|
|
252
|
-
redirect_uris: [https://app.acme.com/callback]
|
|
253
|
-
roles:
|
|
254
|
-
- name: Admin
|
|
255
|
-
permissions: [read, write, delete]
|
|
256
|
-
- name: Viewer
|
|
257
|
-
permissions: [read]
|
|
258
|
-
users:
|
|
259
|
-
- email: admin@acme.com
|
|
260
|
-
given_name: Admin
|
|
261
|
-
family_name: User
|
|
262
|
-
roles: [Admin]
|
|
263
|
-
```
|
|
245
|
+
## Interactive Administration Shell
|
|
246
|
+
|
|
247
|
+
`porta admin` opens the terminal administration shell for a Porta server.
|
|
264
248
|
|
|
265
249
|
```bash
|
|
266
|
-
|
|
267
|
-
|
|
250
|
+
porta admin --server https://identity.example.com
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The command requires interactive stdin and stdout. It rejects `--json` and `--force`. Login uses
|
|
254
|
+
the same OIDC Authorization Code with PKCE flow as `porta login`: the CLI opens a browser when
|
|
255
|
+
available and offers the manual authorization URL/callback flow when it cannot.
|
|
256
|
+
|
|
257
|
+
After verification, the organization chooser opens automatically without selecting an organization
|
|
258
|
+
for you. Use the Organizations menu to switch context or create an organization from its name,
|
|
259
|
+
optional slug, and optional default locale. Creation selects the returned organization immediately.
|
|
260
|
+
The selected context is held only for the running shell and does not change authentication or grant
|
|
261
|
+
permissions.
|
|
268
262
|
|
|
269
|
-
|
|
270
|
-
|
|
263
|
+
When no verified session is available, the admin UI immediately opens an **Authentication
|
|
264
|
+
required** dialog. Choose **Authenticate** (focused by default, so Enter works) to start the existing
|
|
265
|
+
browser/manual OIDC flow, or choose **Quit**. The dialog returns after cancellation or a failed
|
|
266
|
+
attempt, so the shell never leaves you on an unusable disabled screen.
|
|
271
267
|
|
|
272
|
-
|
|
273
|
-
|
|
268
|
+
Press `F10` to open the hamburger menu containing `Who am I…`, `Reauthenticate`, and `Quit`.
|
|
269
|
+
`Who am I…` shows the server-bound verified identity. After selecting an organization, the Users
|
|
270
|
+
menu supports browse, search, status filters, create, invite, detail, history, profile, credentials,
|
|
271
|
+
and lifecycle actions according to the verified permissions. Use `Ctrl-R` to reauthenticate;
|
|
272
|
+
replacing credentials for a different server requires explicit confirmation.
|
|
273
|
+
|
|
274
|
+
Use `--insecure` only for deliberate local testing. The shell displays a persistent warning because
|
|
275
|
+
that flag disables TLS certificate validation.
|
|
276
|
+
|
|
277
|
+
## Environment Portability
|
|
278
|
+
|
|
279
|
+
Export selected data to a strict JSON manifest:
|
|
280
|
+
|
|
281
|
+
```console
|
|
282
|
+
porta export manifest \
|
|
283
|
+
--organization acme \
|
|
284
|
+
--category organizations \
|
|
285
|
+
--category applications_authorization \
|
|
286
|
+
--all-applications \
|
|
287
|
+
--output acme-porta.json
|
|
288
|
+
|
|
289
|
+
porta import manifest acme-porta.json --mode keep-existing
|
|
274
290
|
```
|
|
275
291
|
|
|
292
|
+
Import always previews and validates before confirmation and apply. Existing client secrets,
|
|
293
|
+
passwords, signing keys, sessions, recovery material, and control-plane records are never carried
|
|
294
|
+
by the manifest. Newly created confidential clients return a generated secret once after commit.
|
|
295
|
+
|
|
276
296
|
## JSON Output
|
|
277
297
|
|
|
278
298
|
All commands support `--json` for machine-readable output, making it easy to integrate with scripts and CI pipelines:
|
|
@@ -305,7 +325,7 @@ porta completion > ~/.config/fish/completions/porta.fish
|
|
|
305
325
|
|
|
306
326
|
- [CLI Overview](https://blendsdk.github.io/porta-identity/cli/overview) — Architecture, installation, and authentication
|
|
307
327
|
- [CLI Commands Reference](https://blendsdk.github.io/porta-identity/cli/organizations) — Detailed command documentation
|
|
308
|
-
- [
|
|
328
|
+
- [Environment Portability](https://blendsdk.github.io/porta-identity/cli/provisioning) — Selective manifest export and import
|
|
309
329
|
- [Bootstrap Guide](https://blendsdk.github.io/porta-identity/cli/bootstrap) — Initial server setup with `porta init`
|
|
310
330
|
|
|
311
331
|
## Related Packages
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Shared human-readable formatting for timestamps on administrative surfaces. */
|
|
2
|
+
/** Formats one timestamp in a concise, stable UTC representation. */
|
|
3
|
+
export declare function formatAdminDateTime(value: string): string;
|
|
4
|
+
/** Formats an optional timestamp or returns its context-specific empty label. */
|
|
5
|
+
export declare function formatOptionalAdminDateTime(value: string | null, fallback: string): string;
|
|
6
|
+
//# sourceMappingURL=admin-date-time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-date-time.d.ts","sourceRoot":"","sources":["../../src/admin/admin-date-time.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAiBlF,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUzD;AAED,iFAAiF;AACjF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1F"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** Shared human-readable formatting for timestamps on administrative surfaces. */
|
|
2
|
+
const MONTHS = [
|
|
3
|
+
'Jan',
|
|
4
|
+
'Feb',
|
|
5
|
+
'Mar',
|
|
6
|
+
'Apr',
|
|
7
|
+
'May',
|
|
8
|
+
'Jun',
|
|
9
|
+
'Jul',
|
|
10
|
+
'Aug',
|
|
11
|
+
'Sep',
|
|
12
|
+
'Oct',
|
|
13
|
+
'Nov',
|
|
14
|
+
'Dec',
|
|
15
|
+
];
|
|
16
|
+
/** Formats one timestamp in a concise, stable UTC representation. */
|
|
17
|
+
export function formatAdminDateTime(value) {
|
|
18
|
+
const timestamp = Date.parse(value);
|
|
19
|
+
if (!Number.isFinite(timestamp))
|
|
20
|
+
return 'Unknown';
|
|
21
|
+
const date = new Date(timestamp);
|
|
22
|
+
const day = String(date.getUTCDate()).padStart(2, '0');
|
|
23
|
+
const month = MONTHS[date.getUTCMonth()] ?? 'Unknown';
|
|
24
|
+
const year = date.getUTCFullYear();
|
|
25
|
+
const hours = String(date.getUTCHours()).padStart(2, '0');
|
|
26
|
+
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
|
|
27
|
+
return `${day} ${month} ${year}, ${hours}:${minutes} UTC`;
|
|
28
|
+
}
|
|
29
|
+
/** Formats an optional timestamp or returns its context-specific empty label. */
|
|
30
|
+
export function formatOptionalAdminDateTime(value, fallback) {
|
|
31
|
+
return value === null ? fallback : formatAdminDateTime(value);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=admin-date-time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-date-time.js","sourceRoot":"","sources":["../../src/admin/admin-date-time.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,MAAM,MAAM,GAAG;IACb,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACG,CAAC;AAEX,qEAAqE;AACrE,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,SAAS,CAAC;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,OAAO,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,OAAO,MAAM,CAAC;AAC5D,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,2BAA2B,CAAC,KAAoB,EAAE,QAAgB;IAChF,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Shell composition for the global application and selected-organization client workspaces. */
|
|
2
|
+
import type { View } from '@jsvision/ui';
|
|
3
|
+
import type { AdminDialogSurface } from './application-runtime.js';
|
|
4
|
+
import type { AdminApplicationSession } from './application.js';
|
|
5
|
+
import type { AdminConnectionState } from './state.js';
|
|
6
|
+
/** Dependencies supplied by the existing administration shell. */
|
|
7
|
+
export interface AdminApplicationClientFeaturesOptions {
|
|
8
|
+
/** Shared modal surface owned by the administration application. */
|
|
9
|
+
readonly dialogs: AdminDialogSurface;
|
|
10
|
+
/** Reads the current verified shell state. */
|
|
11
|
+
readonly readState: () => AdminConnectionState;
|
|
12
|
+
/** Reads the current server-bound operation set. */
|
|
13
|
+
readonly readSession: () => AdminApplicationSession | undefined;
|
|
14
|
+
/** Replaces the single main workspace. */
|
|
15
|
+
readonly mountWorkspace: (workspace: View | null) => void;
|
|
16
|
+
/** Focuses one known focusable workspace child. */
|
|
17
|
+
readonly focusView: (view: View) => void;
|
|
18
|
+
/** Reports whether a feature dialog currently owns terminal input. */
|
|
19
|
+
readonly setDialogBusy: (busy: boolean) => void;
|
|
20
|
+
/** Re-enters authentication after a final session failure. */
|
|
21
|
+
readonly requestAuthentication: () => void;
|
|
22
|
+
}
|
|
23
|
+
/** Feature lifecycle used by the shell without exposing controller internals. */
|
|
24
|
+
export interface AdminApplicationClientFeatures {
|
|
25
|
+
/** Applies authentication and selected-organization changes. */
|
|
26
|
+
readonly syncContext: (state: AdminConnectionState, sessionEpoch: number) => void;
|
|
27
|
+
/** Routes one explicit application or client shell command. */
|
|
28
|
+
readonly handleCommand: (command: string) => void;
|
|
29
|
+
/** Cancels the current dialog or feature operation. */
|
|
30
|
+
readonly cancelActiveOperation: () => void;
|
|
31
|
+
/** Clears unsafe ownership when the terminal enters resize recovery. */
|
|
32
|
+
readonly handleRecoverableGeometry: (recoverable: boolean) => void;
|
|
33
|
+
/** Releases both feature owners exactly once. */
|
|
34
|
+
readonly dispose: () => void;
|
|
35
|
+
}
|
|
36
|
+
/** Creates the small feature-specific composition used by the existing shell. */
|
|
37
|
+
export declare function createAdminApplicationClientFeatures(options: AdminApplicationClientFeaturesOptions): AdminApplicationClientFeatures;
|
|
38
|
+
//# sourceMappingURL=application-client-features.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"application-client-features.d.ts","sourceRoot":"","sources":["../../src/admin/application-client-features.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAwCzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEhE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,kEAAkE;AAClE,MAAM,WAAW,qCAAqC;IACpD,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;IACrC,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,oBAAoB,CAAC;IAC/C,oDAAoD;IACpD,QAAQ,CAAC,WAAW,EAAE,MAAM,uBAAuB,GAAG,SAAS,CAAC;IAChE,0CAA0C;IAC1C,QAAQ,CAAC,cAAc,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1D,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACzC,sEAAsE;IACtE,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAChD,8DAA8D;IAC9D,QAAQ,CAAC,qBAAqB,EAAE,MAAM,IAAI,CAAC;CAC5C;AAED,iFAAiF;AACjF,MAAM,WAAW,8BAA8B;IAC7C,gEAAgE;IAChE,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAClF,+DAA+D;IAC/D,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,uDAAuD;IACvD,QAAQ,CAAC,qBAAqB,EAAE,MAAM,IAAI,CAAC;IAC3C,wEAAwE;IACxE,QAAQ,CAAC,yBAAyB,EAAE,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI,CAAC;IACnE,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,iFAAiF;AACjF,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,qCAAqC,GAC7C,8BAA8B,CAqlBhC"}
|