@ratio-mcp/dev-server 1.2.0 → 1.4.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/dist/data/scope-webhook-map.d.ts +26 -0
- package/dist/data/scope-webhook-map.d.ts.map +1 -0
- package/dist/data/scope-webhook-map.js +117 -0
- package/dist/data/scope-webhook-map.js.map +1 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -13
- package/dist/index.js.map +1 -1
- package/dist/orchestrated-index.d.ts +4 -9
- package/dist/orchestrated-index.d.ts.map +1 -1
- package/dist/orchestrated-index.js +6 -14
- package/dist/orchestrated-index.js.map +1 -1
- package/dist/orchestrated-server.d.ts +14 -9
- package/dist/orchestrated-server.d.ts.map +1 -1
- package/dist/orchestrated-server.js +86 -48
- package/dist/orchestrated-server.js.map +1 -1
- package/dist/services/session-state.d.ts +50 -16
- package/dist/services/session-state.d.ts.map +1 -1
- package/dist/services/session-state.js +195 -140
- package/dist/services/session-state.js.map +1 -1
- package/dist/services/tool-guard.d.ts +29 -9
- package/dist/services/tool-guard.d.ts.map +1 -1
- package/dist/services/tool-guard.js +83 -60
- package/dist/services/tool-guard.js.map +1 -1
- package/dist/templates/backend/.env.example +3 -0
- package/dist/templates/backend/package.json +2 -1
- package/dist/templates/backend/src/app.module.ts +2 -0
- package/dist/templates/backend/src/oauth/oauth-callback.controller.ts +62 -0
- package/dist/templates/backend/src/oauth/oauth-callback.module.ts +10 -0
- package/dist/templates/backend/src/oauth/oauth-callback.service.ts +158 -0
- package/dist/templates/frontend/.env.example +1 -1
- package/dist/templates/frontend/README.md +16 -0
- package/dist/templates/frontend/eslint.config.js +29 -0
- package/dist/templates/frontend/index.html +4 -4
- package/dist/templates/frontend/jsconfig.json +22 -0
- package/dist/templates/frontend/package.json +14 -11
- package/dist/templates/frontend/public/favicon.svg +1 -0
- package/dist/templates/frontend/public/icons.svg +24 -0
- package/dist/templates/frontend/src/App.css +184 -0
- package/dist/templates/frontend/src/App.jsx +121 -0
- package/dist/templates/frontend/src/assets/hero.png +0 -0
- package/dist/templates/frontend/src/assets/react.svg +1 -0
- package/dist/templates/frontend/src/assets/vite.svg +1 -0
- package/dist/templates/frontend/src/index.css +94 -31
- package/dist/templates/frontend/src/main.jsx +10 -0
- package/dist/templates/frontend/vite.config.js +19 -0
- package/dist/tools/app-management.d.ts.map +1 -1
- package/dist/tools/app-management.js +73 -13
- package/dist/tools/app-management.js.map +1 -1
- package/dist/tools/auth.d.ts.map +1 -1
- package/dist/tools/auth.js +15 -3
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/codegen.d.ts.map +1 -1
- package/dist/tools/codegen.js +312 -18
- package/dist/tools/codegen.js.map +1 -1
- package/dist/tools/gather-requirements.d.ts.map +1 -1
- package/dist/tools/gather-requirements.js +19 -19
- package/dist/tools/gather-requirements.js.map +1 -1
- package/dist/tools/get-status.d.ts +3 -0
- package/dist/tools/get-status.d.ts.map +1 -0
- package/dist/tools/get-status.js +122 -0
- package/dist/tools/get-status.js.map +1 -0
- package/dist/tools/hookdeck.d.ts +3 -0
- package/dist/tools/hookdeck.d.ts.map +1 -0
- package/dist/tools/hookdeck.js +101 -0
- package/dist/tools/hookdeck.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -3
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lifecycle.d.ts.map +1 -1
- package/dist/tools/lifecycle.js +22 -11
- package/dist/tools/lifecycle.js.map +1 -1
- package/dist/tools/reference-data.d.ts.map +1 -1
- package/dist/tools/reference-data.js +6 -4
- package/dist/tools/reference-data.js.map +1 -1
- package/dist/tools/requirements.d.ts.map +1 -1
- package/dist/tools/requirements.js +84 -5
- package/dist/tools/requirements.js.map +1 -1
- package/dist/tools/scaffold.d.ts.map +1 -1
- package/dist/tools/scaffold.js +30 -16
- package/dist/tools/scaffold.js.map +1 -1
- package/dist/tools/submission.js +4 -4
- package/dist/tools/submission.js.map +1 -1
- package/dist/tools/webhooks.d.ts +25 -0
- package/dist/tools/webhooks.d.ts.map +1 -1
- package/dist/tools/webhooks.js +143 -93
- package/dist/tools/webhooks.js.map +1 -1
- package/dist/utils/logger.js +17 -17
- package/dist/utils/logger.js.map +1 -1
- package/package.json +2 -2
- package/dist/templates/frontend/src/App.tsx +0 -32
- package/dist/templates/frontend/src/components/Layout.tsx +0 -53
- package/dist/templates/frontend/src/context/AuthContext.tsx +0 -59
- package/dist/templates/frontend/src/main.tsx +0 -16
- package/dist/templates/frontend/src/pages/Callback.tsx +0 -53
- package/dist/templates/frontend/src/pages/Dashboard.tsx +0 -24
- package/dist/templates/frontend/src/pages/Login.tsx +0 -42
- package/dist/templates/frontend/src/services/api.ts +0 -48
- package/dist/templates/frontend/tsconfig.json +0 -21
- package/dist/templates/frontend/vite.config.ts +0 -15
package/dist/utils/logger.js
CHANGED
|
@@ -73,22 +73,22 @@ function fullStringify(obj, maxLen = 8000) {
|
|
|
73
73
|
}
|
|
74
74
|
export const logger = {
|
|
75
75
|
info: (message, ...args) => {
|
|
76
|
-
const line = `[ratio-
|
|
76
|
+
const line = `[ratio-dev] ${timestamp()} INFO: ${message}${args.length ? ' ' + args.map(a => safeStringify(a)).join(' ') : ''}`;
|
|
77
77
|
console.error(line);
|
|
78
78
|
writeToFile(line);
|
|
79
79
|
},
|
|
80
80
|
warn: (message, ...args) => {
|
|
81
|
-
const line = `[ratio-
|
|
81
|
+
const line = `[ratio-dev] ${timestamp()} WARN: ${message}${args.length ? ' ' + args.map(a => safeStringify(a)).join(' ') : ''}`;
|
|
82
82
|
console.error(line);
|
|
83
83
|
writeToFile(line);
|
|
84
84
|
},
|
|
85
85
|
error: (message, ...args) => {
|
|
86
|
-
const line = `[ratio-
|
|
86
|
+
const line = `[ratio-dev] ${timestamp()} ERROR: ${message}${args.length ? ' ' + args.map(a => safeStringify(a)).join(' ') : ''}`;
|
|
87
87
|
console.error(line);
|
|
88
88
|
writeToFile(line);
|
|
89
89
|
},
|
|
90
90
|
debug: (message, ...args) => {
|
|
91
|
-
const line = `[ratio-
|
|
91
|
+
const line = `[ratio-dev] ${timestamp()} DEBUG: ${message}${args.length ? ' ' + args.map(a => safeStringify(a)).join(' ') : ''}`;
|
|
92
92
|
// Always write to file, only stderr if DEBUG env is set
|
|
93
93
|
if (process.env.DEBUG) {
|
|
94
94
|
console.error(line);
|
|
@@ -97,15 +97,15 @@ export const logger = {
|
|
|
97
97
|
},
|
|
98
98
|
/** Log an incoming tool call with its input parameters */
|
|
99
99
|
toolCall: (toolName, input) => {
|
|
100
|
-
const stderrLine = `[ratio-
|
|
101
|
-
const fileLine = `[ratio-
|
|
100
|
+
const stderrLine = `[ratio-dev] ${timestamp()} TOOL_CALL: ▶ ${toolName} | input: ${safeStringify(input)}`;
|
|
101
|
+
const fileLine = `[ratio-dev] ${timestamp()} TOOL_CALL: ▶ ${toolName} | input: ${fullStringify(input)}`;
|
|
102
102
|
console.error(stderrLine);
|
|
103
103
|
writeToFile(fileLine);
|
|
104
104
|
},
|
|
105
105
|
/** Log a successful tool result */
|
|
106
106
|
toolResult: (toolName, durationMs, result) => {
|
|
107
|
-
const stderrLine = `[ratio-
|
|
108
|
-
const fileLine = `[ratio-
|
|
107
|
+
const stderrLine = `[ratio-dev] ${timestamp()} TOOL_RESULT: ✓ ${toolName} | ${durationMs}ms | output: ${safeStringify(result)}`;
|
|
108
|
+
const fileLine = `[ratio-dev] ${timestamp()} TOOL_RESULT: ✓ ${toolName} | ${durationMs}ms | output: ${fullStringify(result)}`;
|
|
109
109
|
console.error(stderrLine);
|
|
110
110
|
writeToFile(fileLine);
|
|
111
111
|
},
|
|
@@ -114,8 +114,8 @@ export const logger = {
|
|
|
114
114
|
const message = error instanceof Error ? error.message : String(error);
|
|
115
115
|
const stack = error instanceof Error ? error.stack : '';
|
|
116
116
|
const details = error?.details;
|
|
117
|
-
const stderrLine = `[ratio-
|
|
118
|
-
const fileLine = `[ratio-
|
|
117
|
+
const stderrLine = `[ratio-dev] ${timestamp()} TOOL_ERROR: ✗ ${toolName} | ${durationMs}ms | error: ${message}${details ? ` | details: ${safeStringify(details, 500)}` : ''}`;
|
|
118
|
+
const fileLine = `[ratio-dev] ${timestamp()} TOOL_ERROR: ✗ ${toolName} | ${durationMs}ms | error: ${message}${details ? ` | details: ${fullStringify(details)}` : ''}${stack ? `\n STACK: ${stack}` : ''}`;
|
|
119
119
|
console.error(stderrLine);
|
|
120
120
|
writeToFile(fileLine);
|
|
121
121
|
},
|
|
@@ -123,29 +123,29 @@ export const logger = {
|
|
|
123
123
|
apiRequest: (method, url, data) => {
|
|
124
124
|
const body = data ? ` | body: ${safeStringify(data, 500)}` : '';
|
|
125
125
|
const fullBody = data ? ` | body: ${fullStringify(data)}` : '';
|
|
126
|
-
console.error(`[ratio-
|
|
127
|
-
writeToFile(`[ratio-
|
|
126
|
+
console.error(`[ratio-dev] ${timestamp()} API_REQ: → ${method} ${url}${body}`);
|
|
127
|
+
writeToFile(`[ratio-dev] ${timestamp()} API_REQ: → ${method} ${url}${fullBody}`);
|
|
128
128
|
},
|
|
129
129
|
/** Log a successful API response */
|
|
130
130
|
apiResponse: (method, url, status, durationMs, responseData) => {
|
|
131
|
-
console.error(`[ratio-
|
|
132
|
-
writeToFile(`[ratio-
|
|
131
|
+
console.error(`[ratio-dev] ${timestamp()} API_RES: ← ${method} ${url} | ${status} | ${durationMs}ms`);
|
|
132
|
+
writeToFile(`[ratio-dev] ${timestamp()} API_RES: ← ${method} ${url} | ${status} | ${durationMs}ms${responseData ? ` | data: ${fullStringify(responseData)}` : ''}`);
|
|
133
133
|
},
|
|
134
134
|
/** Log a failed API response */
|
|
135
135
|
apiError: (method, url, status, durationMs, errorBody) => {
|
|
136
|
-
const line = `[ratio-
|
|
136
|
+
const line = `[ratio-dev] ${timestamp()} API_ERR: ✗ ${method} ${url} | ${status || 'NO_RESPONSE'} | ${durationMs}ms | body: ${fullStringify(errorBody)}`;
|
|
137
137
|
console.error(line);
|
|
138
138
|
writeToFile(line);
|
|
139
139
|
},
|
|
140
140
|
/** Log session state snapshots for debugging flow issues */
|
|
141
141
|
sessionSnapshot: (label, context) => {
|
|
142
|
-
const line = `[ratio-
|
|
142
|
+
const line = `[ratio-dev] ${timestamp()} SESSION [${label}]: ${fullStringify(context)}`;
|
|
143
143
|
writeToFile(line);
|
|
144
144
|
},
|
|
145
145
|
/** Separator for clarity between flow phases */
|
|
146
146
|
phase: (phaseName, details) => {
|
|
147
147
|
const separator = '═'.repeat(60);
|
|
148
|
-
const line = `\n${separator}\n[ratio-
|
|
148
|
+
const line = `\n${separator}\n[ratio-dev] ${timestamp()} PHASE: ${phaseName}${details ? ` | ${details}` : ''}\n${separator}`;
|
|
149
149
|
writeToFile(line);
|
|
150
150
|
},
|
|
151
151
|
};
|
package/dist/utils/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC3D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,qDAAqD;AACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AAElD,+BAA+B;AAC/B,IAAI,CAAC;IACH,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAAC,MAAM,CAAC,CAAC,wCAAwC,CAAC,CAAC;AAEpD,SAAS,SAAS;IAChB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,CAAC;QACD,cAAc,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC,CAAC,2CAA2C,CAAC,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,GAAY,EAAE,MAAM,GAAG,IAAI;IAChD,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;IACzH,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;YAC7C,IAAI,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC3E,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC;YACrF,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;YAC/B,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,wBAAwB,GAAG,CAAC,MAAM,SAAS,CAAC;QAChF,CAAC;QACD,OAAO,GAAG,IAAI,EAAE,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,GAAY,EAAE,MAAM,GAAG,IAAI;IAChD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACzC,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;YAC/B,OAAO,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,wBAAwB,GAAG,CAAC,MAAM,SAAS,CAAC;QAChF,CAAC;QACD,OAAO,GAAG,IAAI,EAAE,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,EAAE,CAAC,OAAe,EAAE,GAAG,IAAe,EAAE,EAAE;QAC5C,MAAM,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ratio-mcp/dev-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"files": ["dist"],
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
22
|
-
"@ratio-mcp/shared": "^1.
|
|
22
|
+
"@ratio-mcp/shared": "^1.4.0",
|
|
23
23
|
"axios": "^1.7.0",
|
|
24
24
|
"zod": "^3.23.0",
|
|
25
25
|
"archiver": "^7.0.0",
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { Routes, Route, Navigate } from 'react-router-dom';
|
|
2
|
-
import { useAuth } from './context/AuthContext';
|
|
3
|
-
import Layout from './components/Layout';
|
|
4
|
-
import Dashboard from './pages/Dashboard';
|
|
5
|
-
import Login from './pages/Login';
|
|
6
|
-
import Callback from './pages/Callback';
|
|
7
|
-
|
|
8
|
-
function PrivateRoute({ children }: { children: React.ReactNode }) {
|
|
9
|
-
const { isAuthenticated } = useAuth();
|
|
10
|
-
return isAuthenticated ? <>{children}</> : <Navigate to="/login" />;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default function App() {
|
|
14
|
-
return (
|
|
15
|
-
<Routes>
|
|
16
|
-
<Route path="/login" element={<Login />} />
|
|
17
|
-
<Route path="/callback" element={<Callback />} />
|
|
18
|
-
<Route
|
|
19
|
-
path="/*"
|
|
20
|
-
element={
|
|
21
|
-
<PrivateRoute>
|
|
22
|
-
<Layout>
|
|
23
|
-
<Routes>
|
|
24
|
-
<Route path="/" element={<Dashboard />} />
|
|
25
|
-
</Routes>
|
|
26
|
-
</Layout>
|
|
27
|
-
</PrivateRoute>
|
|
28
|
-
}
|
|
29
|
-
/>
|
|
30
|
-
</Routes>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
import { Link } from 'react-router-dom';
|
|
3
|
-
import { useAuth } from '../context/AuthContext';
|
|
4
|
-
|
|
5
|
-
export default function Layout({ children }: { children: ReactNode }) {
|
|
6
|
-
const { logout, merchantId } = useAuth();
|
|
7
|
-
|
|
8
|
-
return (
|
|
9
|
-
<div style={{ display: 'flex', minHeight: '100vh' }}>
|
|
10
|
-
{/* Sidebar */}
|
|
11
|
-
<aside
|
|
12
|
-
style={{
|
|
13
|
-
width: 240,
|
|
14
|
-
background: '#1a1a2e',
|
|
15
|
-
color: '#fff',
|
|
16
|
-
padding: '1.5rem 1rem',
|
|
17
|
-
display: 'flex',
|
|
18
|
-
flexDirection: 'column',
|
|
19
|
-
}}
|
|
20
|
-
>
|
|
21
|
-
<h2 style={{ fontSize: '1.2rem', marginBottom: '2rem' }}>Ratio App</h2>
|
|
22
|
-
<nav style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
|
|
23
|
-
<Link to="/" style={{ color: '#ccc', padding: '0.5rem', borderRadius: 6 }}>
|
|
24
|
-
Dashboard
|
|
25
|
-
</Link>
|
|
26
|
-
{/* Add more nav links here as you build pages */}
|
|
27
|
-
</nav>
|
|
28
|
-
<div style={{ borderTop: '1px solid #333', paddingTop: '1rem', fontSize: '0.85rem' }}>
|
|
29
|
-
<div style={{ color: '#888', marginBottom: '0.5rem' }}>
|
|
30
|
-
Merchant: {merchantId || '—'}
|
|
31
|
-
</div>
|
|
32
|
-
<button
|
|
33
|
-
onClick={logout}
|
|
34
|
-
style={{
|
|
35
|
-
width: '100%',
|
|
36
|
-
background: '#e74c3c',
|
|
37
|
-
border: 'none',
|
|
38
|
-
padding: '0.5rem',
|
|
39
|
-
borderRadius: 6,
|
|
40
|
-
color: '#fff',
|
|
41
|
-
cursor: 'pointer',
|
|
42
|
-
}}
|
|
43
|
-
>
|
|
44
|
-
Logout
|
|
45
|
-
</button>
|
|
46
|
-
</div>
|
|
47
|
-
</aside>
|
|
48
|
-
|
|
49
|
-
{/* Main Content */}
|
|
50
|
-
<main style={{ flex: 1, padding: '2rem' }}>{children}</main>
|
|
51
|
-
</div>
|
|
52
|
-
);
|
|
53
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, useState, useEffect, ReactNode } from 'react';
|
|
2
|
-
import { api } from '../services/api';
|
|
3
|
-
|
|
4
|
-
interface AuthState {
|
|
5
|
-
accessToken: string | null;
|
|
6
|
-
merchantId: string | null;
|
|
7
|
-
isAuthenticated: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface AuthContextType extends AuthState {
|
|
11
|
-
login: (token: string, merchantId: string) => void;
|
|
12
|
-
logout: () => void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const AuthContext = createContext<AuthContextType | null>(null);
|
|
16
|
-
|
|
17
|
-
export function AuthProvider({ children }: { children: ReactNode }) {
|
|
18
|
-
const [auth, setAuth] = useState<AuthState>({
|
|
19
|
-
accessToken: null,
|
|
20
|
-
merchantId: null,
|
|
21
|
-
isAuthenticated: false,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
useEffect(() => {
|
|
25
|
-
// Check for stored token on mount
|
|
26
|
-
const token = sessionStorage.getItem('ratio_access_token');
|
|
27
|
-
const merchant = sessionStorage.getItem('ratio_merchant_id');
|
|
28
|
-
if (token) {
|
|
29
|
-
setAuth({ accessToken: token, merchantId: merchant, isAuthenticated: true });
|
|
30
|
-
api.setToken(token);
|
|
31
|
-
}
|
|
32
|
-
}, []);
|
|
33
|
-
|
|
34
|
-
const login = (token: string, merchantId: string) => {
|
|
35
|
-
sessionStorage.setItem('ratio_access_token', token);
|
|
36
|
-
sessionStorage.setItem('ratio_merchant_id', merchantId);
|
|
37
|
-
api.setToken(token);
|
|
38
|
-
setAuth({ accessToken: token, merchantId, isAuthenticated: true });
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const logout = () => {
|
|
42
|
-
sessionStorage.removeItem('ratio_access_token');
|
|
43
|
-
sessionStorage.removeItem('ratio_merchant_id');
|
|
44
|
-
api.setToken(null);
|
|
45
|
-
setAuth({ accessToken: null, merchantId: null, isAuthenticated: false });
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<AuthContext.Provider value={{ ...auth, login, logout }}>
|
|
50
|
-
{children}
|
|
51
|
-
</AuthContext.Provider>
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function useAuth() {
|
|
56
|
-
const context = useContext(AuthContext);
|
|
57
|
-
if (!context) throw new Error('useAuth must be used within AuthProvider');
|
|
58
|
-
return context;
|
|
59
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import ReactDOM from 'react-dom/client';
|
|
3
|
-
import { BrowserRouter } from 'react-router-dom';
|
|
4
|
-
import App from './App';
|
|
5
|
-
import { AuthProvider } from './context/AuthContext';
|
|
6
|
-
import './index.css';
|
|
7
|
-
|
|
8
|
-
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
9
|
-
<React.StrictMode>
|
|
10
|
-
<BrowserRouter>
|
|
11
|
-
<AuthProvider>
|
|
12
|
-
<App />
|
|
13
|
-
</AuthProvider>
|
|
14
|
-
</BrowserRouter>
|
|
15
|
-
</React.StrictMode>,
|
|
16
|
-
);
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { useNavigate, useSearchParams } from 'react-router-dom';
|
|
3
|
-
import { useAuth } from '../context/AuthContext';
|
|
4
|
-
|
|
5
|
-
export default function Callback() {
|
|
6
|
-
const [searchParams] = useSearchParams();
|
|
7
|
-
const navigate = useNavigate();
|
|
8
|
-
const { login } = useAuth();
|
|
9
|
-
const [error, setError] = useState<string | null>(null);
|
|
10
|
-
|
|
11
|
-
useEffect(() => {
|
|
12
|
-
const code = searchParams.get('code');
|
|
13
|
-
if (!code) {
|
|
14
|
-
setError('No authorization code received.');
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Exchange the auth code for tokens via your backend
|
|
19
|
-
fetch(`${import.meta.env.VITE_API_URL || 'http://localhost:3000/api'}/auth/callback`, {
|
|
20
|
-
method: 'POST',
|
|
21
|
-
headers: { 'Content-Type': 'application/json' },
|
|
22
|
-
body: JSON.stringify({ code }),
|
|
23
|
-
})
|
|
24
|
-
.then((res) => res.json())
|
|
25
|
-
.then((data) => {
|
|
26
|
-
if (data.access_token) {
|
|
27
|
-
login(data.access_token, data.merchant_id || '');
|
|
28
|
-
navigate('/');
|
|
29
|
-
} else {
|
|
30
|
-
setError(data.message || 'Token exchange failed.');
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
.catch(() => setError('Failed to exchange authorization code.'));
|
|
34
|
-
}, [searchParams, login, navigate]);
|
|
35
|
-
|
|
36
|
-
if (error) {
|
|
37
|
-
return (
|
|
38
|
-
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
|
39
|
-
<h2>Authentication Error</h2>
|
|
40
|
-
<p style={{ color: '#e74c3c' }}>{error}</p>
|
|
41
|
-
<button onClick={() => navigate('/login')} style={{ marginTop: '1rem' }}>
|
|
42
|
-
Back to Login
|
|
43
|
-
</button>
|
|
44
|
-
</div>
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
|
50
|
-
<p>Completing sign-in...</p>
|
|
51
|
-
</div>
|
|
52
|
-
);
|
|
53
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { useAuth } from '../context/AuthContext';
|
|
2
|
-
|
|
3
|
-
export default function Dashboard() {
|
|
4
|
-
const { merchantId } = useAuth();
|
|
5
|
-
|
|
6
|
-
return (
|
|
7
|
-
<div>
|
|
8
|
-
<h1 style={{ marginBottom: '1rem' }}>Dashboard</h1>
|
|
9
|
-
<div
|
|
10
|
-
style={{
|
|
11
|
-
background: '#fff',
|
|
12
|
-
borderRadius: 8,
|
|
13
|
-
padding: '1.5rem',
|
|
14
|
-
boxShadow: '0 1px 3px rgba(0,0,0,0.1)',
|
|
15
|
-
}}
|
|
16
|
-
>
|
|
17
|
-
<p>Welcome to your Ratio app. Merchant ID: <strong>{merchantId}</strong></p>
|
|
18
|
-
<p style={{ color: '#666', marginTop: '0.5rem' }}>
|
|
19
|
-
Start building your resource pages — orders, products, customers, etc.
|
|
20
|
-
</p>
|
|
21
|
-
</div>
|
|
22
|
-
</div>
|
|
23
|
-
);
|
|
24
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
export default function Login() {
|
|
2
|
-
const clientId = import.meta.env.VITE_RATIO_CLIENT_ID || '';
|
|
3
|
-
const redirectUri = import.meta.env.VITE_RATIO_REDIRECT_URI || `${window.location.origin}/callback`;
|
|
4
|
-
const dashboardUrl = import.meta.env.VITE_RATIO_DASHBOARD_URL || 'https://adm-apps.gokwik.co';
|
|
5
|
-
|
|
6
|
-
const handleLogin = () => {
|
|
7
|
-
// Redirect to Ratio OAuth consent screen
|
|
8
|
-
const authUrl = `${dashboardUrl}/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code`;
|
|
9
|
-
window.location.href = authUrl;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<div
|
|
14
|
-
style={{
|
|
15
|
-
display: 'flex',
|
|
16
|
-
justifyContent: 'center',
|
|
17
|
-
alignItems: 'center',
|
|
18
|
-
minHeight: '100vh',
|
|
19
|
-
background: '#f0f2f5',
|
|
20
|
-
}}
|
|
21
|
-
>
|
|
22
|
-
<div
|
|
23
|
-
style={{
|
|
24
|
-
background: '#fff',
|
|
25
|
-
padding: '3rem',
|
|
26
|
-
borderRadius: 12,
|
|
27
|
-
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
28
|
-
textAlign: 'center',
|
|
29
|
-
maxWidth: 400,
|
|
30
|
-
}}
|
|
31
|
-
>
|
|
32
|
-
<h1 style={{ marginBottom: '0.5rem' }}>Ratio App</h1>
|
|
33
|
-
<p style={{ color: '#666', marginBottom: '2rem' }}>
|
|
34
|
-
Sign in with your Ratio merchant account to continue.
|
|
35
|
-
</p>
|
|
36
|
-
<button onClick={handleLogin} style={{ width: '100%', padding: '0.75rem' }}>
|
|
37
|
-
Sign in with Ratio
|
|
38
|
-
</button>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
);
|
|
42
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import axios, { AxiosInstance } from 'axios';
|
|
2
|
-
|
|
3
|
-
class ApiService {
|
|
4
|
-
private client: AxiosInstance;
|
|
5
|
-
private token: string | null = null;
|
|
6
|
-
|
|
7
|
-
constructor() {
|
|
8
|
-
this.client = axios.create({
|
|
9
|
-
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:3000/api',
|
|
10
|
-
headers: { 'Content-Type': 'application/json' },
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
// Attach token to every request
|
|
14
|
-
this.client.interceptors.request.use((config) => {
|
|
15
|
-
if (this.token) {
|
|
16
|
-
config.headers.Authorization = `Bearer ${this.token}`;
|
|
17
|
-
}
|
|
18
|
-
return config;
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
setToken(token: string | null) {
|
|
23
|
-
this.token = token;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Generic CRUD helpers — resource pages will use these
|
|
27
|
-
async get<T>(path: string, params?: Record<string, unknown>): Promise<T> {
|
|
28
|
-
const { data } = await this.client.get(path, { params });
|
|
29
|
-
return data;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async post<T>(path: string, body?: unknown): Promise<T> {
|
|
33
|
-
const { data } = await this.client.post(path, body);
|
|
34
|
-
return data;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async put<T>(path: string, body?: unknown): Promise<T> {
|
|
38
|
-
const { data } = await this.client.put(path, body);
|
|
39
|
-
return data;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async delete<T>(path: string): Promise<T> {
|
|
43
|
-
const { data } = await this.client.delete(path);
|
|
44
|
-
return data;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export const api = new ApiService();
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"skipLibCheck": true,
|
|
8
|
-
"moduleResolution": "bundler",
|
|
9
|
-
"allowImportingTsExtensions": true,
|
|
10
|
-
"resolveJsonModule": true,
|
|
11
|
-
"isolatedModules": true,
|
|
12
|
-
"noEmit": true,
|
|
13
|
-
"strict": true,
|
|
14
|
-
"jsx": "react-jsx",
|
|
15
|
-
"baseUrl": ".",
|
|
16
|
-
"paths": {
|
|
17
|
-
"@/*": ["./src/*"]
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"include": ["src"]
|
|
21
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
2
|
-
import react from '@vitejs/plugin-react';
|
|
3
|
-
|
|
4
|
-
export default defineConfig({
|
|
5
|
-
plugins: [react()],
|
|
6
|
-
server: {
|
|
7
|
-
port: 5173,
|
|
8
|
-
proxy: {
|
|
9
|
-
'/api': {
|
|
10
|
-
target: 'http://localhost:3000',
|
|
11
|
-
changeOrigin: true,
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
});
|