@ima-jin/config 0.7.0 → 0.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/dist/{index.mjs → index.cjs} +252 -16
- package/dist/index.d.cts +343 -0
- package/dist/index.d.ts +343 -0
- package/dist/index.js +97 -163
- package/next-headers.cjs +57 -0
- package/package.json +17 -7
- package/src/base-path.ts +4 -4
- package/src/cors.ts +7 -0
- package/src/handles.ts +2 -2
- package/src/index.ts +5 -1
- package/src/rate-limit.ts +54 -0
- package/src/security-headers.ts +45 -0
- package/src/services.ts +47 -4
package/src/services.ts
CHANGED
|
@@ -62,6 +62,9 @@ export const SERVICES: readonly ServiceDefinition[] = [
|
|
|
62
62
|
{ name: 'github', label: 'GitHub', icon: '🐙', description: 'Source code', devPort: 3000, prodPort: 7000, schema: "public", tier: 'core', visibility: 'public', category: 'meta', externalUrl: 'https://github.com/ima-jin/imajin-ai' },
|
|
63
63
|
{ name: 'docs', label: 'Docs', icon: '📄', description: 'API documentation', devPort: 3000, prodPort: 7000, schema: "public", tier: 'core', visibility: 'public', category: 'meta', wwwPath: '/developer-guide' },
|
|
64
64
|
|
|
65
|
+
// Daemon processes — not web apps, no HTTP port exposed
|
|
66
|
+
{ name: 'broker-agent', label: 'Broker Agent', icon: '🤖', description: 'Telegram broker agent — conversational surface for social coordination (#1101)', devPort: 0, prodPort: 0, schema: null, tier: 'core', visibility: 'internal', category: 'infrastructure' },
|
|
67
|
+
|
|
65
68
|
// Connected apps (separate repos) will use the plugin architecture (#249).
|
|
66
69
|
// Not included here — they authenticate via delegated sessions, not the monorepo manifest.
|
|
67
70
|
] as const satisfies readonly ServiceDefinition[];
|
|
@@ -76,7 +79,8 @@ export function getService(name: string): ServiceDefinition | undefined {
|
|
|
76
79
|
/** Get the port for a service in a given environment */
|
|
77
80
|
export function getPort(name: string, env: "dev" | "prod" = "dev"): number | undefined {
|
|
78
81
|
const svc = getService(name);
|
|
79
|
-
|
|
82
|
+
if (!svc) return undefined;
|
|
83
|
+
return env === "prod" ? svc.prodPort : svc.devPort;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
/** Get internal URL for a service (server-side calls) */
|
|
@@ -115,7 +119,7 @@ export function getPublicUrl(
|
|
|
115
119
|
|
|
116
120
|
// Single-domain mode: prefix contains dots (e.g. "dev-jin.imajin.ai/")
|
|
117
121
|
// Build https://{prefix}{name} instead of https://{prefix}-{name}.{domain}
|
|
118
|
-
if (prefix
|
|
122
|
+
if (prefix?.includes(".")) {
|
|
119
123
|
const base = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
120
124
|
// "www" or "kernel" = root of the node, no suffix
|
|
121
125
|
if (name === "www" || name === "kernel") return `https://${base}`;
|
|
@@ -147,8 +151,8 @@ export function buildPublicUrl(
|
|
|
147
151
|
if (explicit) return explicit;
|
|
148
152
|
}
|
|
149
153
|
|
|
150
|
-
const p = servicePrefix ?? (typeof process
|
|
151
|
-
const d = domain ?? (typeof process
|
|
154
|
+
const p = servicePrefix ?? (typeof process === "undefined" ? undefined : process.env.NEXT_PUBLIC_SERVICE_PREFIX) ?? "https://";
|
|
155
|
+
const d = domain ?? (typeof process === "undefined" ? undefined : process.env.NEXT_PUBLIC_DOMAIN) ?? "imajin.ai";
|
|
152
156
|
|
|
153
157
|
// Localhost detection
|
|
154
158
|
if (p.includes("localhost") || d.includes("localhost")) {
|
|
@@ -168,6 +172,45 @@ export function buildPublicUrl(
|
|
|
168
172
|
return getPublicUrl(name, { prefix: match, domain: d });
|
|
169
173
|
}
|
|
170
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Build an ABSOLUTE public URL for a service — for use OUTSIDE the browser
|
|
177
|
+
* origin: email links, Stripe/webhook return/success URLs, externally shared
|
|
178
|
+
* links, and cross-node links. Unlike buildPublicUrl(), this never returns a
|
|
179
|
+
* relative path.
|
|
180
|
+
*
|
|
181
|
+
* Resolution order:
|
|
182
|
+
* 1. explicit NEXT_PUBLIC_{NAME}_URL env var (only if already absolute)
|
|
183
|
+
* 2. localhost dev → http://localhost:{devPort} from the canonical port map
|
|
184
|
+
* 3. otherwise an absolute https URL derived from NEXT_PUBLIC_SERVICE_PREFIX
|
|
185
|
+
* + NEXT_PUBLIC_DOMAIN via getPublicUrl()
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* buildPublicUrlAbsolute('chat') → https://jin.imajin.ai/chat (single-domain)
|
|
189
|
+
* buildPublicUrlAbsolute('kernel') → https://jin.imajin.ai (node root)
|
|
190
|
+
*/
|
|
191
|
+
export function buildPublicUrlAbsolute(name: string): string {
|
|
192
|
+
// 1. Explicit per-service override wins if it is already absolute.
|
|
193
|
+
if (typeof process !== "undefined") {
|
|
194
|
+
const explicit = process.env[`NEXT_PUBLIC_${name.toUpperCase()}_URL`];
|
|
195
|
+
if (explicit && /^https?:\/\//.test(explicit)) return explicit;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const prefix =
|
|
199
|
+
(typeof process === "undefined" ? undefined : process.env.NEXT_PUBLIC_SERVICE_PREFIX) ?? "https://";
|
|
200
|
+
const domain =
|
|
201
|
+
(typeof process === "undefined" ? undefined : process.env.NEXT_PUBLIC_DOMAIN) ?? "imajin.ai";
|
|
202
|
+
|
|
203
|
+
// 2. Localhost dev → canonical dev port.
|
|
204
|
+
if (prefix.includes("localhost") || domain.includes("localhost")) {
|
|
205
|
+
const port = getPort(name, "dev");
|
|
206
|
+
return port ? `http://localhost:${port}` : "http://localhost:3000";
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// 3. Force absolute construction (getPublicUrl never returns a relative path).
|
|
210
|
+
const match = prefix.replace(/^https?:\/\//, "").replace(/-$/, "") || undefined;
|
|
211
|
+
return getPublicUrl(name, { prefix: match, domain });
|
|
212
|
+
}
|
|
213
|
+
|
|
171
214
|
/** All service names */
|
|
172
215
|
export const SERVICE_NAMES = SERVICES.map((s) => s.name);
|
|
173
216
|
|