@j-256/ccam 0.1.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +209 -0
  3. package/dist/auth/browser-login.d.ts +14 -0
  4. package/dist/auth/browser-login.js +72 -0
  5. package/dist/auth/manual-login.d.ts +10 -0
  6. package/dist/auth/manual-login.js +33 -0
  7. package/dist/auth/paths.d.ts +4 -0
  8. package/dist/auth/paths.js +15 -0
  9. package/dist/auth/profile-resolver.d.ts +26 -0
  10. package/dist/auth/profile-resolver.js +42 -0
  11. package/dist/auth/profile-store.d.ts +38 -0
  12. package/dist/auth/profile-store.js +125 -0
  13. package/dist/auth/prompt.d.ts +9 -0
  14. package/dist/auth/prompt.js +70 -0
  15. package/dist/bin.d.ts +3 -0
  16. package/dist/bin.js +4 -0
  17. package/dist/client-factory.d.ts +6 -0
  18. package/dist/client-factory.js +40 -0
  19. package/dist/commands/auth.d.ts +77 -0
  20. package/dist/commands/auth.js +387 -0
  21. package/dist/commands/client.d.ts +3 -0
  22. package/dist/commands/client.js +365 -0
  23. package/dist/commands/instance.d.ts +11 -0
  24. package/dist/commands/instance.js +128 -0
  25. package/dist/commands/org-config.d.ts +3 -0
  26. package/dist/commands/org-config.js +31 -0
  27. package/dist/commands/org.d.ts +11 -0
  28. package/dist/commands/org.js +234 -0
  29. package/dist/commands/permission.d.ts +3 -0
  30. package/dist/commands/permission.js +60 -0
  31. package/dist/commands/realm.d.ts +3 -0
  32. package/dist/commands/realm.js +58 -0
  33. package/dist/commands/role.d.ts +3 -0
  34. package/dist/commands/role.js +77 -0
  35. package/dist/commands/service-type.d.ts +3 -0
  36. package/dist/commands/service-type.js +57 -0
  37. package/dist/commands/user.d.ts +14 -0
  38. package/dist/commands/user.js +573 -0
  39. package/dist/error-handler.d.ts +2 -0
  40. package/dist/error-handler.js +28 -0
  41. package/dist/index.d.ts +2 -0
  42. package/dist/index.js +2 -0
  43. package/dist/output/csv.d.ts +3 -0
  44. package/dist/output/csv.js +57 -0
  45. package/dist/output/default-columns.d.ts +2 -0
  46. package/dist/output/default-columns.js +16 -0
  47. package/dist/output/detect.d.ts +4 -0
  48. package/dist/output/detect.js +6 -0
  49. package/dist/output/index.d.ts +15 -0
  50. package/dist/output/index.js +34 -0
  51. package/dist/output/json.d.ts +2 -0
  52. package/dist/output/json.js +10 -0
  53. package/dist/output/shared.d.ts +13 -0
  54. package/dist/output/shared.js +41 -0
  55. package/dist/output/table.d.ts +2 -0
  56. package/dist/output/table.js +72 -0
  57. package/dist/output/types.d.ts +2 -0
  58. package/dist/output/types.js +2 -0
  59. package/dist/output/yaml-fmt.d.ts +2 -0
  60. package/dist/output/yaml-fmt.js +11 -0
  61. package/dist/program.d.ts +3 -0
  62. package/dist/program.js +37 -0
  63. package/dist/shared.d.ts +46 -0
  64. package/dist/shared.js +96 -0
  65. package/dist/tui/App.d.ts +7 -0
  66. package/dist/tui/App.js +30 -0
  67. package/dist/tui/components/AuditTab.d.ts +8 -0
  68. package/dist/tui/components/AuditTab.js +80 -0
  69. package/dist/tui/components/FooterBar.d.ts +17 -0
  70. package/dist/tui/components/FooterBar.js +23 -0
  71. package/dist/tui/components/FullScreenLayout.d.ts +6 -0
  72. package/dist/tui/components/FullScreenLayout.js +11 -0
  73. package/dist/tui/components/HeaderBar.d.ts +5 -0
  74. package/dist/tui/components/HeaderBar.js +10 -0
  75. package/dist/tui/components/InfoTab.d.ts +8 -0
  76. package/dist/tui/components/InfoTab.js +70 -0
  77. package/dist/tui/components/ResourcePicker.d.ts +10 -0
  78. package/dist/tui/components/ResourcePicker.js +36 -0
  79. package/dist/tui/components/SubResourceTab.d.ts +7 -0
  80. package/dist/tui/components/SubResourceTab.js +193 -0
  81. package/dist/tui/components/TabBar.d.ts +11 -0
  82. package/dist/tui/components/TabBar.js +13 -0
  83. package/dist/tui/components/Table.d.ts +32 -0
  84. package/dist/tui/components/Table.js +175 -0
  85. package/dist/tui/context/client.d.ts +7 -0
  86. package/dist/tui/context/client.js +14 -0
  87. package/dist/tui/context/navigation.d.ts +14 -0
  88. package/dist/tui/context/navigation.js +25 -0
  89. package/dist/tui/context/terminal-size.d.ts +9 -0
  90. package/dist/tui/context/terminal-size.js +26 -0
  91. package/dist/tui/format.d.ts +20 -0
  92. package/dist/tui/format.js +57 -0
  93. package/dist/tui/hooks/use-audit-log.d.ts +12 -0
  94. package/dist/tui/hooks/use-audit-log.js +71 -0
  95. package/dist/tui/hooks/use-local-collection.d.ts +8 -0
  96. package/dist/tui/hooks/use-local-collection.js +30 -0
  97. package/dist/tui/hooks/use-paginated-resource.d.ts +23 -0
  98. package/dist/tui/hooks/use-paginated-resource.js +115 -0
  99. package/dist/tui/hooks/use-resource-detail.d.ts +7 -0
  100. package/dist/tui/hooks/use-resource-detail.js +30 -0
  101. package/dist/tui/hooks/use-scroll-window.d.ts +7 -0
  102. package/dist/tui/hooks/use-scroll-window.js +29 -0
  103. package/dist/tui/index.d.ts +2 -0
  104. package/dist/tui/index.js +22 -0
  105. package/dist/tui/navigation.d.ts +11 -0
  106. package/dist/tui/navigation.js +29 -0
  107. package/dist/tui/resource-configs/api-clients.d.ts +3 -0
  108. package/dist/tui/resource-configs/api-clients.js +118 -0
  109. package/dist/tui/resource-configs/index.d.ts +14 -0
  110. package/dist/tui/resource-configs/index.js +28 -0
  111. package/dist/tui/resource-configs/instances.d.ts +3 -0
  112. package/dist/tui/resource-configs/instances.js +24 -0
  113. package/dist/tui/resource-configs/org-configuration.d.ts +3 -0
  114. package/dist/tui/resource-configs/org-configuration.js +28 -0
  115. package/dist/tui/resource-configs/organizations.d.ts +3 -0
  116. package/dist/tui/resource-configs/organizations.js +104 -0
  117. package/dist/tui/resource-configs/permissions.d.ts +3 -0
  118. package/dist/tui/resource-configs/permissions.js +25 -0
  119. package/dist/tui/resource-configs/realms.d.ts +3 -0
  120. package/dist/tui/resource-configs/realms.js +36 -0
  121. package/dist/tui/resource-configs/roles.d.ts +3 -0
  122. package/dist/tui/resource-configs/roles.js +56 -0
  123. package/dist/tui/resource-configs/service-types.d.ts +3 -0
  124. package/dist/tui/resource-configs/service-types.js +24 -0
  125. package/dist/tui/resource-configs/users.d.ts +3 -0
  126. package/dist/tui/resource-configs/users.js +126 -0
  127. package/dist/tui/types.d.ts +99 -0
  128. package/dist/tui/types.js +23 -0
  129. package/dist/tui/views/ResourceDetailView.d.ts +7 -0
  130. package/dist/tui/views/ResourceDetailView.js +123 -0
  131. package/dist/tui/views/ResourceListView.d.ts +6 -0
  132. package/dist/tui/views/ResourceListView.js +140 -0
  133. package/dist/tui/views/ViewRouter.d.ts +2 -0
  134. package/dist/tui/views/ViewRouter.js +60 -0
  135. package/package.json +62 -0
@@ -0,0 +1,123 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useCallback, useMemo } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ import Spinner from 'ink-spinner';
5
+ import { useClient } from '../context/client.js';
6
+ import { useNav } from '../context/navigation.js';
7
+ import { useResourceDetail } from '../hooks/use-resource-detail.js';
8
+ import { TabBar } from '../components/TabBar.js';
9
+ import { InfoTab } from '../components/InfoTab.js';
10
+ import { SubResourceTab } from '../components/SubResourceTab.js';
11
+ import { AuditTab } from '../components/AuditTab.js';
12
+ import { FooterBar } from '../components/FooterBar.js';
13
+ const INFO_TAB_KEY = '__info__';
14
+ export function ResourceDetailView({ config, id }) {
15
+ const client = useClient();
16
+ const nav = useNav();
17
+ // Fetch the resource detail
18
+ const fetchFn = useCallback(() => config.detailFn(client, id), [client, config, id]);
19
+ const { data, loading, error, retry } = useResourceDetail(fetchFn);
20
+ // Tab state
21
+ const allTabs = useMemo(() => {
22
+ const tabs = [{ key: INFO_TAB_KEY, label: 'Info' }];
23
+ for (const tab of config.tabs) {
24
+ tabs.push({ key: tab.key, label: tab.label });
25
+ }
26
+ return tabs;
27
+ }, [config.tabs]);
28
+ const [activeTabKey, setActiveTabKey] = useState(INFO_TAB_KEY);
29
+ const [activatedTabs, setActivatedTabs] = useState(() => new Set([INFO_TAB_KEY]));
30
+ const activeTabIndex = allTabs.findIndex((t) => t.key === activeTabKey);
31
+ const switchToTab = useCallback((index) => {
32
+ if (index < 0 || index >= allTabs.length)
33
+ return;
34
+ const tab = allTabs[index];
35
+ setActiveTabKey(tab.key);
36
+ setActivatedTabs((prev) => {
37
+ if (prev.has(tab.key))
38
+ return prev;
39
+ const next = new Set(prev);
40
+ next.add(tab.key);
41
+ return next;
42
+ });
43
+ }, [allTabs]);
44
+ useInput((input, key) => {
45
+ if (loading)
46
+ return;
47
+ // Error state: only retry and back
48
+ if (error) {
49
+ if (input === 'r')
50
+ retry();
51
+ if (key.escape)
52
+ nav.pop();
53
+ return;
54
+ }
55
+ // Back
56
+ if (key.escape || input === 'q') {
57
+ nav.pop();
58
+ return;
59
+ }
60
+ // Tab switching: Tab / Shift-Tab
61
+ if (key.tab) {
62
+ if (key.shift) {
63
+ // Shift-Tab: previous tab
64
+ const prevIndex = activeTabIndex <= 0 ? allTabs.length - 1 : activeTabIndex - 1;
65
+ switchToTab(prevIndex);
66
+ }
67
+ else {
68
+ // Tab: next tab
69
+ const nextIndex = (activeTabIndex + 1) % allTabs.length;
70
+ switchToTab(nextIndex);
71
+ }
72
+ return;
73
+ }
74
+ // Number keys 1-9: jump to tab
75
+ const num = parseInt(input, 10);
76
+ if (num >= 1 && num <= 9 && num <= allTabs.length) {
77
+ switchToTab(num - 1);
78
+ return;
79
+ }
80
+ });
81
+ // -- Error state --
82
+ if (error) {
83
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", children: ["Error: ", error.message] }), _jsx(Text, { dimColor: true, children: "r:retry Esc:back" })] }));
84
+ }
85
+ // -- Loading state --
86
+ if (loading && !data) {
87
+ return (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsxs(Text, { children: [" Loading ", config.displayName, "..."] })] }));
88
+ }
89
+ if (!data)
90
+ return null;
91
+ // Find the active tab config (for non-info tabs)
92
+ const activeTab = config.tabs.find((t) => t.key === activeTabKey);
93
+ // Footer hints per active tab type
94
+ const footerHints = buildFooterHints(activeTabKey, activeTab);
95
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(TabBar, { tabs: allTabs, activeKey: activeTabKey }), _jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", children: [activeTabKey === INFO_TAB_KEY && (_jsx(InfoTab, { fields: config.fields, data: data, crossLinks: config.crossLinks })), activeTab && activeTab.type !== 'audit' && activatedTabs.has(activeTab.key) && (_jsx(SubResourceTab, { tab: activeTab, parentId: id })), activeTab && activeTab.type === 'audit' && activatedTabs.has(activeTab.key) && (_jsx(AuditTabWrapper, { tab: activeTab, id: id }))] }), _jsx(FooterBar, { hints: footerHints })] }));
96
+ }
97
+ // Wrapper to adapt TabConfig.fetchFn to AuditTab's expected fetchFn signature.
98
+ // The element-type cast (Record<string, unknown> -> AuditLogRecord) is needed
99
+ // because the tab-level fetchFn is typed against the generic record shape that
100
+ // all tab tables use.
101
+ function AuditTabWrapper({ tab, id }) {
102
+ const client = useClient();
103
+ const fetchFn = useCallback((querySize) => tab.fetchFn(client, id, querySize), [client, id, tab]);
104
+ return _jsx(AuditTab, { fetchFn: fetchFn, columns: tab.columns });
105
+ }
106
+ function buildFooterHints(activeTabKey, activeTab) {
107
+ const parts = ['[Tab:next]'];
108
+ if (activeTabKey === INFO_TAB_KEY) {
109
+ parts.push('[j/k:nav]', '[Enter:link]', '[Esc:back]');
110
+ }
111
+ else if (activeTab?.type === 'audit') {
112
+ parts.push('[j/k:scroll]', '[m:more]', '[Esc:back]');
113
+ }
114
+ else {
115
+ // sub-resource tab
116
+ parts.push('[j/k:nav]');
117
+ if (activeTab?.crossLinkTo)
118
+ parts.push('[Enter:open]');
119
+ parts.push('[Esc:back]');
120
+ }
121
+ return parts.join(' ');
122
+ }
123
+ //# sourceMappingURL=ResourceDetailView.js.map
@@ -0,0 +1,6 @@
1
+ import { type ResourceConfig } from '../types.js';
2
+ export interface ResourceListViewProps {
3
+ config: ResourceConfig;
4
+ }
5
+ export declare function ResourceListView({ config }: ResourceListViewProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=ResourceListView.d.ts.map
@@ -0,0 +1,140 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useCallback } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ import Spinner from 'ink-spinner';
5
+ import { useClient } from '../context/client.js';
6
+ import { useNav } from '../context/navigation.js';
7
+ import { usePaginatedResource } from '../hooks/use-paginated-resource.js';
8
+ import { useScrollWindow } from '../hooks/use-scroll-window.js';
9
+ import { useTerminalSize } from '../context/terminal-size.js';
10
+ import { Table } from '../components/Table.js';
11
+ import { FooterBar } from '../components/FooterBar.js';
12
+ import { getSortableColumns } from '../types.js';
13
+ const BORDER_INSET = 2;
14
+ export function ResourceListView({ config }) {
15
+ const client = useClient();
16
+ const nav = useNav();
17
+ const { cols } = useTerminalSize();
18
+ const [highlight, setHighlight] = useState(0);
19
+ const sortableColumns = getSortableColumns(config.columns, 'remote');
20
+ const fetchFn = useCallback((page, size, sort) => config.listFn(client, { page, size, sort }), [client, config]);
21
+ const { data, page, totalPages, totalElements, loading, error, paginated, nextPage, prevPage, retry, currentSort, cycleSort, reverseSort, } = usePaginatedResource(fetchFn);
22
+ const scroll = useScrollWindow(highlight, data.length);
23
+ useInput((input, key) => {
24
+ if (loading)
25
+ return;
26
+ // Error state: only retry and back
27
+ if (error) {
28
+ if (input === 'r')
29
+ retry();
30
+ if (key.escape)
31
+ nav.pop();
32
+ return;
33
+ }
34
+ // Navigation
35
+ if (key.escape) {
36
+ nav.pop();
37
+ return;
38
+ }
39
+ // Vertical movement
40
+ if (input === 'j' || key.downArrow) {
41
+ setHighlight((i) => Math.min(i + 1, data.length - 1));
42
+ }
43
+ if (input === 'k' || key.upArrow) {
44
+ setHighlight((i) => Math.max(i - 1, 0));
45
+ }
46
+ // Jump to first/last
47
+ if (input === 'g') {
48
+ setHighlight(0);
49
+ }
50
+ if (input === 'G') {
51
+ setHighlight(Math.max(0, data.length - 1));
52
+ }
53
+ // Enter: drill into detail
54
+ if (key.return && data.length > 0) {
55
+ const item = data[highlight];
56
+ if (item) {
57
+ const detailView = `${config.name}-detail`;
58
+ nav.push({
59
+ view: detailView,
60
+ label: config.labelFn(item),
61
+ params: { id: String(item[config.idField]) },
62
+ });
63
+ }
64
+ }
65
+ // Pagination / scroll
66
+ if (input === 'n') {
67
+ if (paginated) {
68
+ nextPage();
69
+ setHighlight(0);
70
+ }
71
+ else {
72
+ setHighlight((i) => Math.min(i + scroll.visibleRows, data.length - 1));
73
+ }
74
+ }
75
+ if (input === 'p') {
76
+ if (paginated) {
77
+ prevPage();
78
+ setHighlight(0);
79
+ }
80
+ else {
81
+ setHighlight((i) => Math.max(i - scroll.visibleRows, 0));
82
+ }
83
+ }
84
+ // Sort
85
+ if (input === 's' && sortableColumns.length > 0) {
86
+ cycleSort(sortableColumns);
87
+ setHighlight(0);
88
+ }
89
+ if (input === 'S') {
90
+ reverseSort();
91
+ setHighlight(0);
92
+ }
93
+ // Refresh
94
+ if (input === 'r') {
95
+ retry();
96
+ }
97
+ });
98
+ // -- Error state --
99
+ if (error) {
100
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "red", children: ["Error: ", error.message] }), _jsx(Text, { dimColor: true, children: "r:retry Esc:back" })] }));
101
+ }
102
+ // -- Loading state --
103
+ if (loading && data.length === 0) {
104
+ return (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsxs(Text, { children: [" Loading ", config.displayName, "..."] })] }));
105
+ }
106
+ // -- Footer hints --
107
+ const hintParts = ['[j/k:nav]', '[Enter:open]', '[Esc:back]'];
108
+ if (paginated) {
109
+ hintParts.splice(2, 0, '[n/p:page]');
110
+ }
111
+ else if (scroll.scrollInfo) {
112
+ hintParts.splice(2, 0, '[n/p:scroll]');
113
+ }
114
+ if (sortableColumns.length > 0) {
115
+ hintParts.splice(paginated || scroll.scrollInfo ? 3 : 2, 0, '[s:sort]', '[S:reverse]');
116
+ }
117
+ const hints = hintParts.join(' ');
118
+ // -- Sort label --
119
+ const sortLabel = (() => {
120
+ if (!currentSort)
121
+ return undefined;
122
+ const match = sortableColumns.find((sf) => sf.field === currentSort.field);
123
+ const label = match ? match.label : currentSort.field;
124
+ return `Sort: ${label} ${currentSort.direction}`;
125
+ })();
126
+ // -- Stats label --
127
+ const statsLabel = `${totalElements.toLocaleString()} ${config.displayName}`;
128
+ // -- Page info --
129
+ let pageInfo;
130
+ if (paginated) {
131
+ const start = page * 25 + 1;
132
+ const end = Math.min(start + data.length - 1, totalElements);
133
+ pageInfo = `${start}-${end} of ${totalElements} | Page ${page + 1}/${totalPages}`;
134
+ }
135
+ else {
136
+ pageInfo = `${totalElements} results`;
137
+ }
138
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", children: [_jsxs(Box, { gap: 2, children: [_jsx(Text, { color: "cyan", bold: true, children: config.displayName }), _jsxs(Text, { dimColor: true, children: ["(", totalElements, ")"] }), loading && (_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }))] }), _jsx(Table, { columns: config.columns, data: data, highlightIndex: highlight, visibleRows: scroll.visibleRows, scrollOffset: scroll.scrollOffset, sortKey: currentSort?.field, sortDirection: currentSort?.direction, contentWidth: cols - BORDER_INSET })] }), _jsx(FooterBar, { hints: hints, pageInfo: pageInfo, loading: loading, sortLabel: sortLabel, statsLabel: statsLabel })] }));
139
+ }
140
+ //# sourceMappingURL=ResourceListView.js.map
@@ -0,0 +1,2 @@
1
+ export declare function ViewRouter(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=ViewRouter.d.ts.map
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text } from 'ink';
3
+ import { useNav } from '../context/navigation.js';
4
+ import { ResourcePicker } from '../components/ResourcePicker.js';
5
+ import { ResourceListView } from './ResourceListView.js';
6
+ import { ResourceDetailView } from './ResourceDetailView.js';
7
+ import { getResourceConfig } from '../resource-configs/index.js';
8
+ /**
9
+ * Extract resource name from a ViewType string.
10
+ * Examples:
11
+ * - 'user-list' -> 'user'
12
+ * - 'service-type-detail' -> 'service-type'
13
+ * - 'org-list' -> 'org'
14
+ */
15
+ function getResourceName(viewType) {
16
+ // Strip the last '-list' or '-detail' suffix
17
+ return viewType.replace(/-(?:list|detail)$/, '');
18
+ }
19
+ export function ViewRouter() {
20
+ const { current } = useNav();
21
+ const { view, params } = current;
22
+ // Special case: resource picker
23
+ if (view === 'resource-picker') {
24
+ return _jsx(ResourcePicker, {});
25
+ }
26
+ // Special case: org-config-detail (singleton resource)
27
+ if (view === 'org-config-detail') {
28
+ const config = getResourceConfig('org-configuration');
29
+ return _jsx(ResourceDetailView, { config: config, id: "singleton" });
30
+ }
31
+ // List views: *-list
32
+ if (view.endsWith('-list')) {
33
+ const resourceName = getResourceName(view);
34
+ try {
35
+ const config = getResourceConfig(resourceName);
36
+ return _jsx(ResourceListView, { config: config });
37
+ }
38
+ catch (err) {
39
+ return _jsxs(Text, { color: "red", children: ["Error: ", String(err)] });
40
+ }
41
+ }
42
+ // Detail views: *-detail
43
+ if (view.endsWith('-detail')) {
44
+ const resourceName = getResourceName(view);
45
+ const id = params?.id;
46
+ if (!id) {
47
+ return _jsx(Text, { color: "red", children: "Error: detail view requires id param" });
48
+ }
49
+ try {
50
+ const config = getResourceConfig(resourceName);
51
+ return _jsx(ResourceDetailView, { config: config, id: id }, `${resourceName}-${id}`);
52
+ }
53
+ catch (err) {
54
+ return _jsxs(Text, { color: "red", children: ["Error: ", String(err)] });
55
+ }
56
+ }
57
+ // Unknown view type
58
+ return _jsxs(Text, { color: "red", children: ["Error: unknown view type: ", view] });
59
+ }
60
+ //# sourceMappingURL=ViewRouter.js.map
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@j-256/ccam",
3
+ "version": "0.1.0",
4
+ "description": "CLI for the Salesforce Commerce Cloud Account Manager API",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "ccam": "dist/bin.js"
10
+ },
11
+ "files": [
12
+ "dist/**/*.js",
13
+ "dist/**/*.d.ts",
14
+ "LICENSE",
15
+ "README.md"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "test": "vitest run",
20
+ "test:watch": "vitest",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "dependencies": {
27
+ "ccam-sdk": "0.1.0",
28
+ "chalk": "^5.6.2",
29
+ "cli-table3": "^0.6.5",
30
+ "commander": "^14.0.3",
31
+ "ink": "^7.0.0",
32
+ "ink-spinner": "^5.0.0",
33
+ "open": "^10.2.0",
34
+ "react": "^19.2.5",
35
+ "yaml": "^2.8.3"
36
+ },
37
+ "engines": {
38
+ "node": ">=22"
39
+ },
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "git+https://github.com/j-256/ccam.git"
43
+ },
44
+ "bugs": {
45
+ "url": "https://github.com/j-256/ccam/issues"
46
+ },
47
+ "homepage": "https://github.com/j-256/ccam#readme",
48
+ "keywords": [
49
+ "salesforce",
50
+ "commerce-cloud",
51
+ "sfcc",
52
+ "account-manager",
53
+ "am",
54
+ "demandware",
55
+ "cli"
56
+ ],
57
+ "license": "MIT",
58
+ "devDependencies": {
59
+ "@types/react": "^19.2.14",
60
+ "ink-testing-library": "^4.0.0"
61
+ }
62
+ }