dxcomplete 0.2.1 → 0.2.2
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/.env.example +0 -7
- package/README.md +17 -45
- package/dist/cli.js +0 -22
- package/dist/validate.js +10 -26
- package/docs/model.md +3 -3
- package/docs/taxonomy.md +1 -1
- package/package.json +23 -23
- package/templates/process/README.md +1 -1
- package/dist/http/service.d.ts +0 -7
- package/dist/http/service.js +0 -725
- package/dist/mcp/docs.d.ts +0 -114
- package/dist/mcp/docs.js +0 -626
- package/dist/mcp/server.d.ts +0 -20
- package/dist/mcp/server.js +0 -3059
- package/dist/runtime/auth.d.ts +0 -162
- package/dist/runtime/auth.js +0 -394
- package/dist/runtime/check.d.ts +0 -7
- package/dist/runtime/check.js +0 -16
- package/dist/runtime/config.d.ts +0 -17
- package/dist/runtime/config.js +0 -93
- package/dist/runtime/mongo.d.ts +0 -9
- package/dist/runtime/mongo.js +0 -56
- package/dist/runtime/records.d.ts +0 -427
- package/dist/runtime/records.js +0 -2092
- package/scripts/check-env-surface.mjs +0 -136
- package/scripts/check-public-copy.mjs +0 -263
- package/scripts/check-service-boundary.mjs +0 -63
- package/scripts/runtime-work-order.mjs +0 -506
- package/scripts/smoke-mcp-http.mjs +0 -4026
- package/src/cli.ts +0 -268
- package/src/http/server.ts +0 -314
- package/src/http/service.ts +0 -934
- package/src/init.ts +0 -262
- package/src/install-manifest.ts +0 -144
- package/src/mcp/docs.ts +0 -777
- package/src/mcp/server.ts +0 -4580
- package/src/package-root.ts +0 -31
- package/src/runtime/actor.ts +0 -61
- package/src/runtime/auth.ts +0 -673
- package/src/runtime/check.ts +0 -18
- package/src/runtime/config.ts +0 -128
- package/src/runtime/mongo.ts +0 -89
- package/src/runtime/records.ts +0 -3205
- package/src/runtime/workspace.ts +0 -155
- package/src/upgrade.ts +0 -356
- package/src/validate.ts +0 -141
- package/src/version.ts +0 -16
package/src/runtime/config.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { constants as fsConstants } from "node:fs";
|
|
2
|
-
import { access, readFile } from "node:fs/promises";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
|
|
5
|
-
export type RuntimeOptions = {
|
|
6
|
-
cwd?: string;
|
|
7
|
-
env?: NodeJS.ProcessEnv;
|
|
8
|
-
envFile?: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export type RuntimeConfig = {
|
|
12
|
-
mongodbUri: string;
|
|
13
|
-
databaseName: string;
|
|
14
|
-
googleClientId?: string;
|
|
15
|
-
googleClientSecret?: string;
|
|
16
|
-
serviceProvisioningSecret?: string;
|
|
17
|
-
envFilePath?: string;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export class RuntimeConfigError extends Error {
|
|
21
|
-
constructor(message: string) {
|
|
22
|
-
super(message);
|
|
23
|
-
this.name = "RuntimeConfigError";
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const DEFAULT_ENV_FILE = ".env.local";
|
|
28
|
-
const DEFAULT_DATABASE_NAME = "dxcomplete";
|
|
29
|
-
|
|
30
|
-
export async function loadRuntimeConfig(options: RuntimeOptions = {}): Promise<RuntimeConfig> {
|
|
31
|
-
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
32
|
-
const envFilePath = await resolveEnvFile(cwd, options.envFile);
|
|
33
|
-
const fileEnv = envFilePath ? await parseEnvFile(envFilePath) : {};
|
|
34
|
-
const env = {
|
|
35
|
-
...fileEnv,
|
|
36
|
-
...(options.env ?? process.env)
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const mongodbUri = readRequiredEnv(env, "DXC_MONGODB_URI");
|
|
40
|
-
const databaseName = readOptionalEnv(env, "DXC_DATABASE_NAME") ?? DEFAULT_DATABASE_NAME;
|
|
41
|
-
const googleClientId = readOptionalEnv(env, "DXC_GOOGLE_CLIENT_ID");
|
|
42
|
-
const googleClientSecret = readOptionalEnv(env, "DXC_GOOGLE_CLIENT_SECRET");
|
|
43
|
-
const serviceProvisioningSecret = readOptionalEnv(env, "DXC_SERVICE_PROVISIONING_SECRET");
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
mongodbUri,
|
|
47
|
-
databaseName,
|
|
48
|
-
...(googleClientId ? { googleClientId } : {}),
|
|
49
|
-
...(googleClientSecret ? { googleClientSecret } : {}),
|
|
50
|
-
...(serviceProvisioningSecret ? { serviceProvisioningSecret } : {}),
|
|
51
|
-
envFilePath
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async function resolveEnvFile(cwd: string, envFile?: string): Promise<string | undefined> {
|
|
56
|
-
if (envFile) {
|
|
57
|
-
const explicitPath = path.resolve(cwd, envFile);
|
|
58
|
-
if (!(await fileExists(explicitPath))) {
|
|
59
|
-
throw new RuntimeConfigError(`Env file not found: ${explicitPath}`);
|
|
60
|
-
}
|
|
61
|
-
return explicitPath;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const defaultPath = path.join(cwd, DEFAULT_ENV_FILE);
|
|
65
|
-
return (await fileExists(defaultPath)) ? defaultPath : undefined;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async function parseEnvFile(filePath: string): Promise<NodeJS.ProcessEnv> {
|
|
69
|
-
const content = await readFile(filePath, "utf8");
|
|
70
|
-
const parsed: NodeJS.ProcessEnv = {};
|
|
71
|
-
|
|
72
|
-
for (const [index, rawLine] of content.split(/\r?\n/).entries()) {
|
|
73
|
-
const trimmed = rawLine.trim();
|
|
74
|
-
if (!trimmed || trimmed.startsWith("#")) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const line = trimmed.startsWith("export ") ? trimmed.slice("export ".length).trim() : trimmed;
|
|
79
|
-
const equalsIndex = line.indexOf("=");
|
|
80
|
-
if (equalsIndex === -1) {
|
|
81
|
-
throw new RuntimeConfigError(`Invalid env line ${index + 1} in ${filePath}. Expected KEY=value.`);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const key = line.slice(0, equalsIndex).trim();
|
|
85
|
-
const value = line.slice(equalsIndex + 1).trim();
|
|
86
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
87
|
-
throw new RuntimeConfigError(`Invalid env key "${key}" on line ${index + 1} in ${filePath}.`);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
parsed[key] = unquote(value);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return parsed;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function readRequiredEnv(env: NodeJS.ProcessEnv, key: string): string {
|
|
97
|
-
const value = readOptionalEnv(env, key);
|
|
98
|
-
if (!value) {
|
|
99
|
-
throw new RuntimeConfigError(
|
|
100
|
-
`${key} is required. Create .env.local from .env.example or export ${key} before running this command.`
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
return value;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function readOptionalEnv(env: NodeJS.ProcessEnv, key: string): string | undefined {
|
|
107
|
-
const value = env[key]?.trim();
|
|
108
|
-
return value ? value : undefined;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function unquote(value: string): string {
|
|
112
|
-
if (
|
|
113
|
-
(value.startsWith("\"") && value.endsWith("\"")) ||
|
|
114
|
-
(value.startsWith("'") && value.endsWith("'"))
|
|
115
|
-
) {
|
|
116
|
-
return value.slice(1, -1);
|
|
117
|
-
}
|
|
118
|
-
return value;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async function fileExists(filePath: string): Promise<boolean> {
|
|
122
|
-
try {
|
|
123
|
-
await access(filePath, fsConstants.F_OK);
|
|
124
|
-
return true;
|
|
125
|
-
} catch {
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
}
|
package/src/runtime/mongo.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { MongoClient, type Db } from "mongodb";
|
|
2
|
-
import {
|
|
3
|
-
OAUTH_AUTH_REQUESTS_COLLECTION,
|
|
4
|
-
OAUTH_CLIENTS_COLLECTION,
|
|
5
|
-
OAUTH_CODES_COLLECTION,
|
|
6
|
-
OAUTH_TOKENS_COLLECTION,
|
|
7
|
-
WORKSPACE_SERVICE_CLIENTS_COLLECTION,
|
|
8
|
-
WORKSPACE_MEMBERSHIPS_COLLECTION
|
|
9
|
-
} from "./auth.js";
|
|
10
|
-
import { loadRuntimeConfig, type RuntimeConfig, type RuntimeOptions } from "./config.js";
|
|
11
|
-
import {
|
|
12
|
-
DXCOMPLETE_TICKET_COLLECTION_NAME,
|
|
13
|
-
INDEX_COLLECTION_NAMES,
|
|
14
|
-
READABLE_ID_COLLECTION_NAMES,
|
|
15
|
-
READABLE_ID_SEQUENCES_COLLECTION,
|
|
16
|
-
migrateLegacyIntakeItemsToDxcompleteTickets
|
|
17
|
-
} from "./records.js";
|
|
18
|
-
|
|
19
|
-
export type DxRuntime = {
|
|
20
|
-
config: RuntimeConfig;
|
|
21
|
-
client: MongoClient;
|
|
22
|
-
db: Db;
|
|
23
|
-
close: () => Promise<void>;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export async function connectRuntime(options: RuntimeOptions = {}): Promise<DxRuntime> {
|
|
27
|
-
const config = await loadRuntimeConfig(options);
|
|
28
|
-
const client = new MongoClient(config.mongodbUri, {
|
|
29
|
-
serverSelectionTimeoutMS: 10000
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
await client.connect();
|
|
33
|
-
const db = client.db(config.databaseName);
|
|
34
|
-
await db.command({ ping: 1 });
|
|
35
|
-
await migrateLegacyIntakeItemsToDxcompleteTickets(db);
|
|
36
|
-
await ensureIndexes(db);
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
config,
|
|
40
|
-
client,
|
|
41
|
-
db,
|
|
42
|
-
close: () => client.close()
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async function ensureIndexes(db: Db): Promise<void> {
|
|
47
|
-
await Promise.all(
|
|
48
|
-
INDEX_COLLECTION_NAMES.map(async (collectionName) => {
|
|
49
|
-
const collection = db.collection(collectionName);
|
|
50
|
-
await collection.createIndex({ recordType: 1, createdAt: -1 });
|
|
51
|
-
await collection.createIndex({ workspaceId: 1, recordType: 1, createdAt: -1 });
|
|
52
|
-
await collection.createIndex({ "links.toId": 1 });
|
|
53
|
-
await collection.createIndex({ workspaceId: 1, "links.toId": 1 });
|
|
54
|
-
|
|
55
|
-
if ((READABLE_ID_COLLECTION_NAMES as readonly string[]).includes(collectionName)) {
|
|
56
|
-
await collection.createIndex(
|
|
57
|
-
{ workspaceId: 1, readableId: 1 },
|
|
58
|
-
{
|
|
59
|
-
unique: true,
|
|
60
|
-
partialFilterExpression: { readableId: { $exists: true } }
|
|
61
|
-
}
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (collectionName === DXCOMPLETE_TICKET_COLLECTION_NAME) {
|
|
66
|
-
await collection.createIndex({ "fields.ownerActorId": 1, archivedAt: 1, updatedAt: -1 });
|
|
67
|
-
await collection.createIndex({ "fields.entries.addressedToActorId": 1, "fields.entries.readAt": 1 });
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (collectionName === "journal_entries") {
|
|
71
|
-
await collection.createIndex({ workspaceId: 1, "fields.kind": 1, archivedAt: 1, createdAt: 1 });
|
|
72
|
-
await collection.createIndex({ workspaceId: 1, archivedAt: 1, createdAt: 1 });
|
|
73
|
-
}
|
|
74
|
-
})
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
await Promise.all([
|
|
78
|
-
db.collection(WORKSPACE_MEMBERSHIPS_COLLECTION).createIndex({ workspaceId: 1, email: 1 }, { unique: true }),
|
|
79
|
-
db.collection(WORKSPACE_MEMBERSHIPS_COLLECTION).createIndex({ provider: 1, providerSubject: 1 }),
|
|
80
|
-
db.collection(WORKSPACE_SERVICE_CLIENTS_COLLECTION).createIndex({ workspaceId: 1, clientId: 1 }, { unique: true }),
|
|
81
|
-
db.collection(WORKSPACE_SERVICE_CLIENTS_COLLECTION).createIndex({ clientId: 1 }, { unique: true }),
|
|
82
|
-
db.collection(OAUTH_CLIENTS_COLLECTION).createIndex({ clientId: 1 }, { unique: true }),
|
|
83
|
-
db.collection(OAUTH_AUTH_REQUESTS_COLLECTION).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }),
|
|
84
|
-
db.collection(OAUTH_CODES_COLLECTION).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }),
|
|
85
|
-
db.collection(OAUTH_TOKENS_COLLECTION).createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 }),
|
|
86
|
-
db.collection(OAUTH_TOKENS_COLLECTION).createIndex({ workspaceId: 1, "actor.actorId": 1 }),
|
|
87
|
-
db.collection(READABLE_ID_SEQUENCES_COLLECTION).createIndex({ workspaceId: 1, recordType: 1 }, { unique: true })
|
|
88
|
-
]);
|
|
89
|
-
}
|