@rubytech/create-maxy-code 0.1.348 → 0.1.349
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/package.json +1 -1
- package/payload/platform/lib/graph-style/dist/index.d.ts +1 -1
- package/payload/platform/lib/graph-style/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-style/dist/index.js +20 -12
- package/payload/platform/lib/graph-style/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-style/src/__tests__/parity.test.ts +9 -9
- package/payload/platform/lib/graph-style/src/index.ts +20 -12
- package/payload/platform/lib/graph-write/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-write/dist/index.js +3 -2
- package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-write/src/index.ts +3 -2
- package/payload/platform/neo4j/schema.cypher +110 -31
- package/payload/platform/plugins/.claude-plugin/marketplace.json +5 -0
- package/payload/platform/plugins/admin/hooks/lib/maxy-mcp-plugins.txt +1 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +36 -3
- package/payload/platform/plugins/docs/references/calendar-booking.md +1 -1
- package/payload/platform/plugins/docs/references/joblogic.md +28 -0
- package/payload/platform/plugins/docs/references/memory-guide.md +1 -1
- package/payload/platform/plugins/joblogic/.claude-plugin/plugin.json +21 -0
- package/payload/platform/plugins/joblogic/PLUGIN.md +182 -0
- package/payload/platform/plugins/joblogic/lib/mcp-spawn-tee/index.js +193 -0
- package/payload/platform/plugins/joblogic/lib/mcp-spawn-tee/package.json +3 -0
- package/payload/platform/plugins/joblogic/mcp/dist/index.d.ts +2 -0
- package/payload/platform/plugins/joblogic/mcp/dist/index.d.ts.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/dist/index.js +229 -0
- package/payload/platform/plugins/joblogic/mcp/dist/index.js.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.d.ts +31 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.d.ts.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.js +78 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/auth.js.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/client.d.ts +35 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/client.d.ts.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/client.js +106 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/client.js.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.d.ts +8 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.d.ts.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.js +41 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/idempotency.js.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.d.ts +21 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.d.ts.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.js +47 -0
- package/payload/platform/plugins/joblogic/mcp/dist/lib/secrets.js.map +1 -0
- package/payload/platform/plugins/joblogic/mcp/package.json +10 -0
- package/payload/platform/plugins/joblogic/skills/joblogic/SKILL.md +32 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relationship-patterns.test.js +28 -22
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/relationship-patterns.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-cypher-drift.test.js +8 -4
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-cypher-drift.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-write-path-task802.test.js +39 -10
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/schema-write-path-task802.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/relationship-patterns.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/relationship-patterns.js +1 -1
- package/payload/platform/plugins/memory/references/schema-construction.md +152 -57
- package/payload/platform/plugins/memory/references/schema-trades.md +22 -24
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +46 -0
- package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
- package/payload/server/public/assets/{AdminLoginScreens-B_5wYcR-.js → AdminLoginScreens-BEzoTk56.js} +1 -1
- package/payload/server/public/assets/{AdminShell-CMV3XY-s.js → AdminShell-BG7YD4UO.js} +1 -1
- package/payload/server/public/assets/{Checkbox-LplFUKpb.js → Checkbox-CvTFOczj.js} +1 -1
- package/payload/server/public/assets/{OperatorConversations-C4Cx814-.css → OperatorConversations-CnP9Y6g2.css} +1 -1
- package/payload/server/public/assets/{admin-3QQtd7j2.js → admin-Bhxa1HOy.js} +1 -1
- package/payload/server/public/assets/{browser-D5q26eZL.js → browser-BAQFuyma.js} +1 -1
- package/payload/server/public/assets/calendar-sSr6zUjW.js +1 -0
- package/payload/server/public/assets/chat-ZH4Fsyu0.js +1 -0
- package/payload/server/public/assets/{data-HwT5wPmj.js → data-CH6GNBO3.js} +1 -1
- package/payload/server/public/assets/{graph-DFQbqmi9.js → graph-DbGjFYPS.js} +1 -1
- package/payload/server/public/assets/graph-labels-IGIEr-uc.js +1 -0
- package/payload/server/public/assets/{operator-BlCyq4q1.js → operator-Ba5afDyM.js} +1 -1
- package/payload/server/public/assets/{page-drg1V-yA.js → page-D7uwMUOy.js} +1 -1
- package/payload/server/public/assets/{public-BVjeYfsD.js → public-DikYWzOd.js} +1 -1
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +4 -4
- package/payload/server/public/chat.html +5 -5
- package/payload/server/public/data.html +4 -4
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +6 -6
- package/payload/server/public/operator.html +7 -7
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +32 -15
- package/payload/server/public/assets/calendar-Csbdj7rp.js +0 -1
- package/payload/server/public/assets/chat-Ct86qtMI.js +0 -1
- package/payload/server/public/assets/graph-labels-kCti2CaC.js +0 -1
- /package/payload/server/public/assets/{OperatorConversations-Bp-g80PM.js → OperatorConversations-DU8CqO-z.js} +0 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { initStderrTee } from "../../../../lib/mcp-stderr-tee/dist/index.js";
|
|
2
|
+
initStderrTee("joblogic");
|
|
3
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { lifelineTool } from "../../../../lib/mcp-lifeline/dist/index.js";
|
|
7
|
+
import { readStore, setCredentials, setEngineerMap, resolveEngineer } from "./lib/secrets.js";
|
|
8
|
+
import { getBearer } from "./lib/auth.js";
|
|
9
|
+
import { jlRequest, jlCreate } from "./lib/client.js";
|
|
10
|
+
// Plugin-system boot tolerance: module init must never throw; tools/list is
|
|
11
|
+
// enumerated with empty env, so account context is resolved per call. Tools are
|
|
12
|
+
// always registered (registering zero with empty env would hide them from the
|
|
13
|
+
// admin allowlist entirely); each handler refuses per-call when context or creds
|
|
14
|
+
// are absent.
|
|
15
|
+
const ACCOUNT_ID = process.env.ACCOUNT_ID ?? null;
|
|
16
|
+
const PLATFORM_ROOT = process.env.PLATFORM_ROOT ?? null;
|
|
17
|
+
function creds() {
|
|
18
|
+
if (!ACCOUNT_ID || !PLATFORM_ROOT)
|
|
19
|
+
return "absent";
|
|
20
|
+
return readStore(PLATFORM_ROOT, ACCOUNT_ID) ? "present" : "absent";
|
|
21
|
+
}
|
|
22
|
+
process.stderr.write(`[joblogic] op=init account=${ACCOUNT_ID ?? "null"} creds=${creds()}\n`);
|
|
23
|
+
function refuseNoAccount(tool) {
|
|
24
|
+
process.stderr.write(`[joblogic] tool=${tool} refuse reason=no-account-context\n`);
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: `${tool} cannot execute: launched without ACCOUNT_ID/PLATFORM_ROOT (metadata-only mode).`,
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
isError: true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function refuseNoCreds(tool) {
|
|
36
|
+
process.stderr.write(`[joblogic] tool=${tool} refuse reason=no-creds\n`);
|
|
37
|
+
return {
|
|
38
|
+
content: [
|
|
39
|
+
{
|
|
40
|
+
type: "text",
|
|
41
|
+
text: `${tool} cannot execute: no JobLogic credentials set for this account. Run joblogic-credentials-set.`,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
isError: true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function ok(data) {
|
|
48
|
+
return {
|
|
49
|
+
content: [
|
|
50
|
+
{ type: "text", text: typeof data === "string" ? data : JSON.stringify(data, null, 2) },
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function fail(msg) {
|
|
55
|
+
return { content: [{ type: "text", text: msg }], isError: true };
|
|
56
|
+
}
|
|
57
|
+
function withStore(tool) {
|
|
58
|
+
if (!ACCOUNT_ID || !PLATFORM_ROOT)
|
|
59
|
+
return { refusal: refuseNoAccount(tool) };
|
|
60
|
+
const store = readStore(PLATFORM_ROOT, ACCOUNT_ID);
|
|
61
|
+
if (!store)
|
|
62
|
+
return { refusal: refuseNoCreds(tool) };
|
|
63
|
+
return { store };
|
|
64
|
+
}
|
|
65
|
+
const server = new McpServer({ name: "joblogic", version: "0.1.0" });
|
|
66
|
+
const body = z.record(z.unknown());
|
|
67
|
+
// --- Management ----------------------------------------------------------
|
|
68
|
+
lifelineTool(server, "joblogic-credentials-set", "Store this account's JobLogic integration credentials (OAuth client_credentials) and company tenant id. environment is 'uat' (test) or 'production'. Get client_id/secret from a JobLogic Support ticket; the source IP must be whitelisted by JobLogic.", {
|
|
69
|
+
clientId: z.string(),
|
|
70
|
+
clientSecret: z.string(),
|
|
71
|
+
tenantId: z.string().describe("Company tenant id, required on every call"),
|
|
72
|
+
environment: z.enum(["uat", "production"]),
|
|
73
|
+
}, async ({ clientId, clientSecret, tenantId, environment }) => {
|
|
74
|
+
if (!ACCOUNT_ID || !PLATFORM_ROOT)
|
|
75
|
+
return refuseNoAccount("joblogic-credentials-set");
|
|
76
|
+
try {
|
|
77
|
+
setCredentials(PLATFORM_ROOT, ACCOUNT_ID, { clientId, clientSecret, tenantId, environment });
|
|
78
|
+
return ok(`Stored JobLogic ${environment} credentials for tenant ${tenantId}.`);
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
return fail(`joblogic-credentials-set failed: ${e.message}`);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
lifelineTool(server, "joblogic-connection-status", "Probe JobLogic auth: acquire a token and report environment + tenant. Use to confirm the credentials and source-IP whitelisting work before relying on the connector.", {}, async () => {
|
|
85
|
+
const r = withStore("joblogic-connection-status");
|
|
86
|
+
if ("refusal" in r)
|
|
87
|
+
return r.refusal;
|
|
88
|
+
try {
|
|
89
|
+
await getBearer(r.store, ACCOUNT_ID, { force: true });
|
|
90
|
+
return ok({ environment: r.store.environment, tenantId: r.store.tenantId, token: "acquired" });
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
return fail(`joblogic-connection-status failed: ${e.message}`);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
lifelineTool(server, "joblogic-engineer-map-set", "Map sender phone numbers (E.164) to JobLogic engineer ids, so a voice-noted write is attributed to the engineer who reported it. Merges with existing entries.", { entries: z.record(z.string()).describe('e.g. {"+447700900001":"eng-7"}') }, async ({ entries }) => {
|
|
97
|
+
const r = withStore("joblogic-engineer-map-set");
|
|
98
|
+
if ("refusal" in r)
|
|
99
|
+
return r.refusal;
|
|
100
|
+
try {
|
|
101
|
+
setEngineerMap(PLATFORM_ROOT, ACCOUNT_ID, entries);
|
|
102
|
+
return ok(`Stored ${Object.keys(entries).length} engineer mapping(s).`);
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
return fail(`joblogic-engineer-map-set failed: ${e.message}`);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
lifelineTool(server, "joblogic-engineer-map-list", "List the stored sender-phone → JobLogic engineer id mappings for this account.", {}, async () => {
|
|
109
|
+
const r = withStore("joblogic-engineer-map-list");
|
|
110
|
+
if ("refusal" in r)
|
|
111
|
+
return r.refusal;
|
|
112
|
+
return ok(r.store.engineerMap);
|
|
113
|
+
});
|
|
114
|
+
// --- Read factory --------------------------------------------------------
|
|
115
|
+
function readTool(tool, entity, path, description) {
|
|
116
|
+
lifelineTool(server, tool, description, { query: z.record(z.string()).optional().describe("Optional JobLogic query params, e.g. { id: '123' } or filters") }, async ({ query }) => {
|
|
117
|
+
const r = withStore(tool);
|
|
118
|
+
if ("refusal" in r)
|
|
119
|
+
return r.refusal;
|
|
120
|
+
try {
|
|
121
|
+
return ok(await jlRequest({ store: r.store, accountId: ACCOUNT_ID, method: "GET", path, entity, tool, query }));
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
return fail(`${tool} failed: ${e.message}`);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
// --- Write (create, idempotent) factory ---------------------------------
|
|
129
|
+
function createToolFactory(tool, entity, path, description, attributable) {
|
|
130
|
+
const schema = {
|
|
131
|
+
idemKey: z
|
|
132
|
+
.string()
|
|
133
|
+
.describe("Idempotency key — a retry with the same key returns the first record and sends nothing. Derive it deterministically from the write's natural key."),
|
|
134
|
+
body: body.describe(`${entity} body (fields per the JobLogic Postman reference; provisional until UAT-confirmed)`),
|
|
135
|
+
};
|
|
136
|
+
if (attributable) {
|
|
137
|
+
schema.senderPhone = z
|
|
138
|
+
.string()
|
|
139
|
+
.optional()
|
|
140
|
+
.describe("Sender phone (E.164); resolved to an engineer id via the engineer map and stamped on the write.");
|
|
141
|
+
}
|
|
142
|
+
lifelineTool(server, tool, description, schema, async (a) => {
|
|
143
|
+
const r = withStore(tool);
|
|
144
|
+
if ("refusal" in r)
|
|
145
|
+
return r.refusal;
|
|
146
|
+
let writeBody = a.body;
|
|
147
|
+
if (attributable && a.senderPhone) {
|
|
148
|
+
const eng = resolveEngineer(r.store, a.senderPhone);
|
|
149
|
+
// The map is the trusted attribution source: a resolved engineerId wins
|
|
150
|
+
// over any caller-supplied body.engineerId.
|
|
151
|
+
if (eng)
|
|
152
|
+
writeBody = { ...a.body, engineerId: eng };
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
return ok(await jlCreate({
|
|
156
|
+
store: r.store,
|
|
157
|
+
accountId: ACCOUNT_ID,
|
|
158
|
+
platformRoot: PLATFORM_ROOT,
|
|
159
|
+
path,
|
|
160
|
+
entity,
|
|
161
|
+
tool,
|
|
162
|
+
idemKey: a.idemKey,
|
|
163
|
+
body: writeBody,
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
catch (e) {
|
|
167
|
+
return fail(`${tool} failed: ${e.message}`);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// --- Update / transition (POST, non-idempotent — caller supplies the id) --
|
|
172
|
+
function postTool(tool, entity, path, description) {
|
|
173
|
+
lifelineTool(server, tool, description, { body: body.describe(`${entity} body — MUST include the record id`) }, async ({ body: b }) => {
|
|
174
|
+
const r = withStore(tool);
|
|
175
|
+
if ("refusal" in r)
|
|
176
|
+
return r.refusal;
|
|
177
|
+
try {
|
|
178
|
+
return ok(await jlRequest({ store: r.store, accountId: ACCOUNT_ID, method: "POST", path, entity, tool, body: b }));
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
return fail(`${tool} failed: ${e.message}`);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
// --- Lifecycle registrations (paths provisional vs the Postman collection) -
|
|
186
|
+
readTool("joblogic-customer-list", "Customer", "Customer/GetAll", "List JobLogic customers.");
|
|
187
|
+
readTool("joblogic-customer-get", "Customer", "Customer/GetById", "Get one JobLogic customer by id (pass { id }).");
|
|
188
|
+
createToolFactory("joblogic-customer-create", "Customer", "Customer/Create", "Create a JobLogic customer.", false);
|
|
189
|
+
postTool("joblogic-customer-update", "Customer", "Customer/Update", "Update a JobLogic customer (body includes id).");
|
|
190
|
+
readTool("joblogic-site-list", "Site", "Site/GetAll", "List JobLogic sites.");
|
|
191
|
+
readTool("joblogic-site-get", "Site", "Site/GetById", "Get one JobLogic site by id.");
|
|
192
|
+
createToolFactory("joblogic-site-create", "Site", "Site/Create", "Create a JobLogic site.", false);
|
|
193
|
+
postTool("joblogic-site-update", "Site", "Site/Update", "Update a JobLogic site (body includes id).");
|
|
194
|
+
readTool("joblogic-job-list", "Job", "Job/GetAll", "List JobLogic jobs.");
|
|
195
|
+
readTool("joblogic-job-get", "Job", "Job/GetById", "Get one JobLogic job by id.");
|
|
196
|
+
createToolFactory("joblogic-job-create", "Job", "Job/Create", "Create a JobLogic job.", false);
|
|
197
|
+
postTool("joblogic-job-update", "Job", "Job/Update", "Update a JobLogic job (body includes id).");
|
|
198
|
+
postTool("joblogic-job-set-status", "Job", "Job/SetStatus", "Set a job's status (body includes id + status).");
|
|
199
|
+
postTool("joblogic-job-approve", "Job", "Job/Approve", "Approve a job (body includes id).");
|
|
200
|
+
readTool("joblogic-engineer-list", "Engineer", "Engineer/GetAll", "List JobLogic engineers.");
|
|
201
|
+
readTool("joblogic-engineer-get", "Engineer", "Engineer/GetById", "Get one JobLogic engineer by id.");
|
|
202
|
+
readTool("joblogic-visit-search-planner", "Visit", "Visit/SearchPlanner", "Search the JobLogic visit planner (pass date/engineer filters in query).");
|
|
203
|
+
readTool("joblogic-visit-get", "Visit", "Visit/GetById", "Get one JobLogic visit by id.");
|
|
204
|
+
createToolFactory("joblogic-visit-create", "Visit", "Visit/Create", "Create a JobLogic visit.", true);
|
|
205
|
+
postTool("joblogic-visit-update", "Visit", "Visit/Update", "Update a JobLogic visit (body includes id).");
|
|
206
|
+
postTool("joblogic-visit-deploy", "Visit", "Visit/Deploy", "Deploy a JobLogic visit to an engineer (body includes id).");
|
|
207
|
+
postTool("joblogic-visit-cancel", "Visit", "Visit/Cancel", "Cancel a JobLogic visit (body includes id).");
|
|
208
|
+
readTool("joblogic-quote-list", "Quote", "Quote/GetAll", "List JobLogic quotes.");
|
|
209
|
+
readTool("joblogic-quote-get", "Quote", "Quote/GetById", "Get one JobLogic quote by id.");
|
|
210
|
+
createToolFactory("joblogic-quote-create", "Quote", "Quote/Create", "Create a JobLogic quote.", false);
|
|
211
|
+
postTool("joblogic-quote-approve", "Quote", "Quote/Approve", "Approve a JobLogic quote (body includes id).");
|
|
212
|
+
readTool("joblogic-invoice-list", "Invoice", "Invoice/GetAll", "List JobLogic invoices.");
|
|
213
|
+
readTool("joblogic-invoice-get", "Invoice", "Invoice/GetById", "Get one JobLogic invoice by id.");
|
|
214
|
+
createToolFactory("joblogic-invoice-create", "Invoice", "Invoice/Create", "Create (raise) a JobLogic invoice.", false);
|
|
215
|
+
createToolFactory("joblogic-invoice-payment-create", "InvoicePayment", "Invoice/Payment/Create", "Record a payment against a JobLogic invoice.", false);
|
|
216
|
+
readTool("joblogic-asset-list", "Asset", "Asset/GetAll", "List JobLogic assets.");
|
|
217
|
+
readTool("joblogic-asset-get", "Asset", "Asset/GetById", "Get one JobLogic asset by id.");
|
|
218
|
+
createToolFactory("joblogic-asset-create", "Asset", "Asset/Create", "Create a JobLogic asset.", false);
|
|
219
|
+
postTool("joblogic-asset-update", "Asset", "Asset/Update", "Update a JobLogic asset (body includes id).");
|
|
220
|
+
readTool("joblogic-timesheet-list", "Timesheet", "Timesheet/GetAll", "List JobLogic timesheets.");
|
|
221
|
+
createToolFactory("joblogic-timesheet-create", "Timesheet", "Timesheet/Create", "Create a JobLogic timesheet entry.", true);
|
|
222
|
+
postTool("joblogic-timesheet-update", "Timesheet", "Timesheet/Update", "Update a JobLogic timesheet entry (body includes id).");
|
|
223
|
+
createToolFactory("joblogic-jobcost-create", "JobCost", "JobCost/Create", "Create a JobLogic job-cost line. Set body.kind to Labour|Material|Travel|Mileage|Expense.", true);
|
|
224
|
+
postTool("joblogic-jobcost-update", "JobCost", "JobCost/Update", "Update a JobLogic job-cost line (body includes id).");
|
|
225
|
+
createToolFactory("joblogic-note-create", "Note", "Note/Create", "Create a note on a job/visit (e.g. a voice-note transcript).", true);
|
|
226
|
+
readTool("joblogic-attachment-url-generate", "Attachment", "Attachment/GenerateUrl", "Generate an upload URL for an attachment (field photo etc.).");
|
|
227
|
+
const transport = new StdioServerTransport();
|
|
228
|
+
await server.connect(transport);
|
|
229
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC;AAC7E,aAAa,CAAC,UAAU,CAAC,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAgB,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEtD,4EAA4E;AAC5E,gFAAgF;AAChF,8EAA8E;AAC9E,iFAAiF;AACjF,cAAc;AACd,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC;AAClD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC;AAExD,SAAS,KAAK;IACZ,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa;QAAE,OAAO,QAAQ,CAAC;IACnD,OAAO,SAAS,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;AACrE,CAAC;AACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,UAAU,IAAI,MAAM,UAAU,KAAK,EAAE,IAAI,CAAC,CAAC;AAE9F,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,IAAI,qCAAqC,CAAC,CAAC;IACnF,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,GAAG,IAAI,kFAAkF;aAChG;SACF;QACD,OAAO,EAAE,IAAa;KACvB,CAAC;AACJ,CAAC;AACD,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,IAAI,2BAA2B,CAAC,CAAC;IACzE,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,GAAG,IAAI,8FAA8F;aAC5G;SACF;QACD,OAAO,EAAE,IAAa;KACvB,CAAC;AACJ,CAAC;AACD,SAAS,EAAE,CAAC,IAAa;IACvB,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;SACjG;KACF,CAAC;AACJ,CAAC;AACD,SAAS,IAAI,CAAC,GAAW;IACvB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,IAAa,EAAE,CAAC;AACrF,CAAC;AAID,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa;QAAE,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;IAC7E,MAAM,KAAK,GAAG,SAAS,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;IACpD,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;AACrE,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AAEnC,4EAA4E;AAC5E,YAAY,CACV,MAAM,EACN,0BAA0B,EAC1B,0PAA0P,EAC1P;IACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,2CAA2C,CAAC;IAC1E,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;CAC3C,EACD,KAAK,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE;IAC1D,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa;QAAE,OAAO,eAAe,CAAC,0BAA0B,CAAC,CAAC;IACtF,IAAI,CAAC;QACH,cAAc,CAAC,aAAa,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;QAC7F,OAAO,EAAE,CAAC,mBAAmB,WAAW,2BAA2B,QAAQ,GAAG,CAAC,CAAC;IAClF,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,oCAAqC,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC,CACF,CAAC;AAEF,YAAY,CACV,MAAM,EACN,4BAA4B,EAC5B,uKAAuK,EACvK,EAAE,EACF,KAAK,IAAI,EAAE;IACT,MAAM,CAAC,GAAG,SAAS,CAAC,4BAA4B,CAAC,CAAC;IAClD,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,OAAO,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,UAAW,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IACjG,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,sCAAuC,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC,CACF,CAAC;AAEF,YAAY,CACV,MAAM,EACN,2BAA2B,EAC3B,gKAAgK,EAChK,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,gCAAgC,CAAC,EAAE,EAC5E,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;IACpB,MAAM,CAAC,GAAG,SAAS,CAAC,2BAA2B,CAAC,CAAC;IACjD,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,OAAO,CAAC;IACrC,IAAI,CAAC;QACH,cAAc,CAAC,aAAc,EAAE,UAAW,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,EAAE,CAAC,UAAU,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,uBAAuB,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,IAAI,CAAC,qCAAsC,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC,CACF,CAAC;AAEF,YAAY,CACV,MAAM,EACN,4BAA4B,EAC5B,gFAAgF,EAChF,EAAE,EACF,KAAK,IAAI,EAAE;IACT,MAAM,CAAC,GAAG,SAAS,CAAC,4BAA4B,CAAC,CAAC;IAClD,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,OAAO,CAAC;IACrC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC,CACF,CAAC;AAEF,4EAA4E;AAC5E,SAAS,QAAQ,CAAC,IAAY,EAAE,MAAc,EAAE,IAAY,EAAE,WAAmB;IAC/E,YAAY,CACV,MAAM,EACN,IAAI,EACJ,WAAW,EACX,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+DAA+D,CAAC,EAAE,EACpH,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,SAAS,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC,OAAO,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,MAAM,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,UAAW,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACnH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,GAAG,IAAI,YAAa,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,SAAS,iBAAiB,CAAC,IAAY,EAAE,MAAc,EAAE,IAAY,EAAE,WAAmB,EAAE,YAAqB;IAC/G,MAAM,MAAM,GAAiC;QAC3C,OAAO,EAAE,CAAC;aACP,MAAM,EAAE;aACR,QAAQ,CACP,mJAAmJ,CACpJ;QACH,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,oFAAoF,CAAC;KACnH,CAAC;IACF,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,WAAW,GAAG,CAAC;aACnB,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,iGAAiG,CAAC,CAAC;IACjH,CAAC;IACD,YAAY,CACV,MAAM,EACN,IAAI,EACJ,WAAW,EACX,MAAM,EACN,KAAK,EAAE,CAA2E,EAAE,EAAE;QACpF,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,SAAS,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC,OAAO,CAAC;QACrC,IAAI,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC;QACvB,IAAI,YAAY,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,eAAe,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;YACpD,wEAAwE;YACxE,4CAA4C;YAC5C,IAAI,GAAG;gBAAE,SAAS,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;QACtD,CAAC;QACD,IAAI,CAAC;YACH,OAAO,EAAE,CACP,MAAM,QAAQ,CAAC;gBACb,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,SAAS,EAAE,UAAW;gBACtB,YAAY,EAAE,aAAc;gBAC5B,IAAI;gBACJ,MAAM;gBACN,IAAI;gBACJ,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,IAAI,EAAE,SAAS;aAChB,CAAC,CACH,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,GAAG,IAAI,YAAa,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,SAAS,QAAQ,CAAC,IAAY,EAAE,MAAc,EAAE,IAAY,EAAE,WAAmB;IAC/E,YAAY,CACV,MAAM,EACN,IAAI,EACJ,WAAW,EACX,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,oCAAoC,CAAC,EAAE,EACtE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAqC,EAAE,EAAE;QACvD,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,SAAS,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC,OAAO,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,EAAE,CAAC,MAAM,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,UAAW,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACtH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,GAAG,IAAI,YAAa,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,QAAQ,CAAC,wBAAwB,EAAE,UAAU,EAAE,iBAAiB,EAAE,0BAA0B,CAAC,CAAC;AAC9F,QAAQ,CAAC,uBAAuB,EAAE,UAAU,EAAE,kBAAkB,EAAE,gDAAgD,CAAC,CAAC;AACpH,iBAAiB,CAAC,0BAA0B,EAAE,UAAU,EAAE,iBAAiB,EAAE,6BAA6B,EAAE,KAAK,CAAC,CAAC;AACnH,QAAQ,CAAC,0BAA0B,EAAE,UAAU,EAAE,iBAAiB,EAAE,gDAAgD,CAAC,CAAC;AAEtH,QAAQ,CAAC,oBAAoB,EAAE,MAAM,EAAE,aAAa,EAAE,sBAAsB,CAAC,CAAC;AAC9E,QAAQ,CAAC,mBAAmB,EAAE,MAAM,EAAE,cAAc,EAAE,8BAA8B,CAAC,CAAC;AACtF,iBAAiB,CAAC,sBAAsB,EAAE,MAAM,EAAE,aAAa,EAAE,yBAAyB,EAAE,KAAK,CAAC,CAAC;AACnG,QAAQ,CAAC,sBAAsB,EAAE,MAAM,EAAE,aAAa,EAAE,4CAA4C,CAAC,CAAC;AAEtG,QAAQ,CAAC,mBAAmB,EAAE,KAAK,EAAE,YAAY,EAAE,qBAAqB,CAAC,CAAC;AAC1E,QAAQ,CAAC,kBAAkB,EAAE,KAAK,EAAE,aAAa,EAAE,6BAA6B,CAAC,CAAC;AAClF,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,YAAY,EAAE,wBAAwB,EAAE,KAAK,CAAC,CAAC;AAC/F,QAAQ,CAAC,qBAAqB,EAAE,KAAK,EAAE,YAAY,EAAE,2CAA2C,CAAC,CAAC;AAClG,QAAQ,CAAC,yBAAyB,EAAE,KAAK,EAAE,eAAe,EAAE,iDAAiD,CAAC,CAAC;AAC/G,QAAQ,CAAC,sBAAsB,EAAE,KAAK,EAAE,aAAa,EAAE,mCAAmC,CAAC,CAAC;AAE5F,QAAQ,CAAC,wBAAwB,EAAE,UAAU,EAAE,iBAAiB,EAAE,0BAA0B,CAAC,CAAC;AAC9F,QAAQ,CAAC,uBAAuB,EAAE,UAAU,EAAE,kBAAkB,EAAE,kCAAkC,CAAC,CAAC;AAEtG,QAAQ,CAAC,+BAA+B,EAAE,OAAO,EAAE,qBAAqB,EAAE,0EAA0E,CAAC,CAAC;AACtJ,QAAQ,CAAC,oBAAoB,EAAE,OAAO,EAAE,eAAe,EAAE,+BAA+B,CAAC,CAAC;AAC1F,iBAAiB,CAAC,uBAAuB,EAAE,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,IAAI,CAAC,CAAC;AACtG,QAAQ,CAAC,uBAAuB,EAAE,OAAO,EAAE,cAAc,EAAE,6CAA6C,CAAC,CAAC;AAC1G,QAAQ,CAAC,uBAAuB,EAAE,OAAO,EAAE,cAAc,EAAE,4DAA4D,CAAC,CAAC;AACzH,QAAQ,CAAC,uBAAuB,EAAE,OAAO,EAAE,cAAc,EAAE,6CAA6C,CAAC,CAAC;AAE1G,QAAQ,CAAC,qBAAqB,EAAE,OAAO,EAAE,cAAc,EAAE,uBAAuB,CAAC,CAAC;AAClF,QAAQ,CAAC,oBAAoB,EAAE,OAAO,EAAE,eAAe,EAAE,+BAA+B,CAAC,CAAC;AAC1F,iBAAiB,CAAC,uBAAuB,EAAE,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,KAAK,CAAC,CAAC;AACvG,QAAQ,CAAC,wBAAwB,EAAE,OAAO,EAAE,eAAe,EAAE,8CAA8C,CAAC,CAAC;AAE7G,QAAQ,CAAC,uBAAuB,EAAE,SAAS,EAAE,gBAAgB,EAAE,yBAAyB,CAAC,CAAC;AAC1F,QAAQ,CAAC,sBAAsB,EAAE,SAAS,EAAE,iBAAiB,EAAE,iCAAiC,CAAC,CAAC;AAClG,iBAAiB,CAAC,yBAAyB,EAAE,SAAS,EAAE,gBAAgB,EAAE,oCAAoC,EAAE,KAAK,CAAC,CAAC;AACvH,iBAAiB,CAAC,iCAAiC,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,8CAA8C,EAAE,KAAK,CAAC,CAAC;AAExJ,QAAQ,CAAC,qBAAqB,EAAE,OAAO,EAAE,cAAc,EAAE,uBAAuB,CAAC,CAAC;AAClF,QAAQ,CAAC,oBAAoB,EAAE,OAAO,EAAE,eAAe,EAAE,+BAA+B,CAAC,CAAC;AAC1F,iBAAiB,CAAC,uBAAuB,EAAE,OAAO,EAAE,cAAc,EAAE,0BAA0B,EAAE,KAAK,CAAC,CAAC;AACvG,QAAQ,CAAC,uBAAuB,EAAE,OAAO,EAAE,cAAc,EAAE,6CAA6C,CAAC,CAAC;AAE1G,QAAQ,CAAC,yBAAyB,EAAE,WAAW,EAAE,kBAAkB,EAAE,2BAA2B,CAAC,CAAC;AAClG,iBAAiB,CAAC,2BAA2B,EAAE,WAAW,EAAE,kBAAkB,EAAE,oCAAoC,EAAE,IAAI,CAAC,CAAC;AAC5H,QAAQ,CAAC,2BAA2B,EAAE,WAAW,EAAE,kBAAkB,EAAE,uDAAuD,CAAC,CAAC;AAEhI,iBAAiB,CAAC,yBAAyB,EAAE,SAAS,EAAE,gBAAgB,EAAE,2FAA2F,EAAE,IAAI,CAAC,CAAC;AAC7K,QAAQ,CAAC,yBAAyB,EAAE,SAAS,EAAE,gBAAgB,EAAE,qDAAqD,CAAC,CAAC;AAExH,iBAAiB,CAAC,sBAAsB,EAAE,MAAM,EAAE,aAAa,EAAE,8DAA8D,EAAE,IAAI,CAAC,CAAC;AACvI,QAAQ,CAAC,kCAAkC,EAAE,YAAY,EAAE,wBAAwB,EAAE,8DAA8D,CAAC,CAAC;AAErJ,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { JlStore, JlEnvironment } from "./secrets.js";
|
|
2
|
+
/** Strip credential-shaped substrings and cap length before an upstream error
|
|
3
|
+
* body is put into a thrown message that may reach a tool response/transcript. */
|
|
4
|
+
export declare function sanitizeErrorBody(text: string): string;
|
|
5
|
+
export declare function identityBaseFor(env: JlEnvironment): string;
|
|
6
|
+
export declare function apiBaseFor(env: JlEnvironment): string;
|
|
7
|
+
export type FetchLike = (url: string, init: {
|
|
8
|
+
method: string;
|
|
9
|
+
headers: Record<string, string>;
|
|
10
|
+
body?: string;
|
|
11
|
+
}) => Promise<{
|
|
12
|
+
ok: boolean;
|
|
13
|
+
status: number;
|
|
14
|
+
text: () => Promise<string>;
|
|
15
|
+
}>;
|
|
16
|
+
export interface Token {
|
|
17
|
+
accessToken: string;
|
|
18
|
+
expiresIn: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function acquireToken(store: JlStore, opts?: {
|
|
21
|
+
fetchImpl?: FetchLike;
|
|
22
|
+
}): Promise<Token>;
|
|
23
|
+
/** Return a valid bearer, refreshing if cached is stale or force=true.
|
|
24
|
+
* reason drives the op=token-refresh line; first acquisition logs op=token-acquire only. */
|
|
25
|
+
export declare function getBearer(store: JlStore, accountId: string, opts?: {
|
|
26
|
+
force?: boolean;
|
|
27
|
+
fetchImpl?: FetchLike;
|
|
28
|
+
}): Promise<string>;
|
|
29
|
+
/** Test seam: clear the per-process cache. */
|
|
30
|
+
export declare function _resetTokenCache(): void;
|
|
31
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAa3D;mFACmF;AACnF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAE1D;AACD,wBAAgB,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAErD;AAED,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KACrE,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAM3E,MAAM,WAAW,KAAK;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,SAAS,CAAA;CAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CA6BvG;AAQD;6FAC6F;AAC7F,wBAAsB,SAAS,CAC7B,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAO,GACpD,OAAO,CAAC,MAAM,CAAC,CAUjB;AAED,8CAA8C;AAC9C,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
const IDENTITY_BASE = {
|
|
2
|
+
uat: "https://uatidentityserver.joblogic.com",
|
|
3
|
+
production: "https://identityserver.joblogic.com",
|
|
4
|
+
};
|
|
5
|
+
const API_BASE = {
|
|
6
|
+
uat: "https://uatapi.joblogic.com",
|
|
7
|
+
production: "https://api.joblogic.com",
|
|
8
|
+
};
|
|
9
|
+
/** Refresh when the cached token is within this window of expiry. */
|
|
10
|
+
const REFRESH_THRESHOLD_MS = 120_000;
|
|
11
|
+
/** Strip credential-shaped substrings and cap length before an upstream error
|
|
12
|
+
* body is put into a thrown message that may reach a tool response/transcript. */
|
|
13
|
+
export function sanitizeErrorBody(text) {
|
|
14
|
+
return text
|
|
15
|
+
.replace(/client_secret=[^&\s"]*/gi, "client_secret=***")
|
|
16
|
+
.replace(/client_id=[^&\s"]*/gi, "client_id=***")
|
|
17
|
+
.replace(/Bearer\s+[A-Za-z0-9._-]+/gi, "Bearer ***")
|
|
18
|
+
.slice(0, 300);
|
|
19
|
+
}
|
|
20
|
+
export function identityBaseFor(env) {
|
|
21
|
+
return IDENTITY_BASE[env];
|
|
22
|
+
}
|
|
23
|
+
export function apiBaseFor(env) {
|
|
24
|
+
return API_BASE[env];
|
|
25
|
+
}
|
|
26
|
+
export async function acquireToken(store, opts = {}) {
|
|
27
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
28
|
+
const url = `${identityBaseFor(store.environment)}/connect/token`;
|
|
29
|
+
const body = new URLSearchParams({
|
|
30
|
+
grant_type: "client_credentials",
|
|
31
|
+
client_id: store.clientId,
|
|
32
|
+
client_secret: store.clientSecret,
|
|
33
|
+
}).toString();
|
|
34
|
+
const started = Date.now();
|
|
35
|
+
const res = await fetchImpl(url, {
|
|
36
|
+
method: "POST",
|
|
37
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json" },
|
|
38
|
+
body,
|
|
39
|
+
});
|
|
40
|
+
const text = await res.text();
|
|
41
|
+
// The token request carried client_secret; some identity servers echo request
|
|
42
|
+
// params in a 4xx body. Strip secrets and cap length before the message can
|
|
43
|
+
// reach a tool response / transcript.
|
|
44
|
+
if (!res.ok)
|
|
45
|
+
throw new Error(`token endpoint ${res.status}: ${sanitizeErrorBody(text)}`);
|
|
46
|
+
let raw;
|
|
47
|
+
try {
|
|
48
|
+
raw = JSON.parse(text);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
throw new Error(`token endpoint non-JSON: ${text}`);
|
|
52
|
+
}
|
|
53
|
+
if (!raw.access_token)
|
|
54
|
+
throw new Error(`token endpoint missing access_token: ${text}`);
|
|
55
|
+
const expiresIn = raw.expires_in ?? 3600;
|
|
56
|
+
process.stderr.write(`[joblogic] op=token-acquire ok=true expiresInS=${expiresIn} ms=${Date.now() - started}\n`);
|
|
57
|
+
return { accessToken: raw.access_token, expiresIn };
|
|
58
|
+
}
|
|
59
|
+
const tokenCache = new Map();
|
|
60
|
+
/** Return a valid bearer, refreshing if cached is stale or force=true.
|
|
61
|
+
* reason drives the op=token-refresh line; first acquisition logs op=token-acquire only. */
|
|
62
|
+
export async function getBearer(store, accountId, opts = {}) {
|
|
63
|
+
const cached = tokenCache.get(accountId);
|
|
64
|
+
const fresh = cached && cached.expiresAt - REFRESH_THRESHOLD_MS > Date.now();
|
|
65
|
+
if (fresh && !opts.force)
|
|
66
|
+
return cached.accessToken;
|
|
67
|
+
if (cached) {
|
|
68
|
+
process.stderr.write(`[joblogic] op=token-refresh reason=${opts.force ? "401" : "pre-expiry"} ok=true\n`);
|
|
69
|
+
}
|
|
70
|
+
const tok = await acquireToken(store, { fetchImpl: opts.fetchImpl });
|
|
71
|
+
tokenCache.set(accountId, { accessToken: tok.accessToken, expiresAt: Date.now() + tok.expiresIn * 1000 });
|
|
72
|
+
return tok.accessToken;
|
|
73
|
+
}
|
|
74
|
+
/** Test seam: clear the per-process cache. */
|
|
75
|
+
export function _resetTokenCache() {
|
|
76
|
+
tokenCache.clear();
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { JlStore } from "./secrets.js";
|
|
2
|
+
import { type FetchLike } from "./auth.js";
|
|
3
|
+
export type AccessFaultKind = "auth" | "whitelist" | "network";
|
|
4
|
+
export declare function classifyAccessFault(status: number): AccessFaultKind;
|
|
5
|
+
export interface BaseArgs {
|
|
6
|
+
store: JlStore;
|
|
7
|
+
accountId: string;
|
|
8
|
+
method: "GET" | "POST";
|
|
9
|
+
/** path under /api/v1/, e.g. "Customer/GetAll". */
|
|
10
|
+
path: string;
|
|
11
|
+
/** entity label for the observability line. */
|
|
12
|
+
entity: string;
|
|
13
|
+
/** tool name for the observability line. */
|
|
14
|
+
tool: string;
|
|
15
|
+
/** extra query params (merged with tenantId). */
|
|
16
|
+
query?: Record<string, string>;
|
|
17
|
+
/** request body for POST. tenantId is also injected into the body for writes. */
|
|
18
|
+
body?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/** A read or generic call. Performs one silent re-acquire on a 401. */
|
|
21
|
+
export declare function jlRequest(args: BaseArgs, opts?: {
|
|
22
|
+
fetchImpl?: FetchLike;
|
|
23
|
+
}): Promise<unknown>;
|
|
24
|
+
/** A create with idempotency. idemKey lookup short-circuits a duplicate send.
|
|
25
|
+
* platformRoot is threaded explicitly (the ledger lives under the account secrets dir). */
|
|
26
|
+
export interface JlCreateArgs extends Omit<BaseArgs, "method"> {
|
|
27
|
+
platformRoot: string;
|
|
28
|
+
idemKey: string;
|
|
29
|
+
/** field on the response carrying the new record id (default "id"). */
|
|
30
|
+
idField?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function jlCreate(args: JlCreateArgs, opts?: {
|
|
33
|
+
fetchImpl?: FetchLike;
|
|
34
|
+
}): Promise<unknown>;
|
|
35
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAA4C,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAGrF,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAE/D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAInE;AAMD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AA2BD,uEAAuE;AACvE,wBAAsB,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,SAAS,CAAA;CAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAoCtG;AAED;4FAC4F;AAC5F,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5D,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,SAAS,CAAA;CAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAoCzG"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// JobLogic REST wrapper. Injects Bearer + tenantId on every call, emits the
|
|
2
|
+
// observability lifeline, classifies any 401/403/network failure as an
|
|
3
|
+
// access-fault, and performs exactly one silent token re-acquire on a 401.
|
|
4
|
+
import { randomBytes } from "node:crypto";
|
|
5
|
+
import { apiBaseFor, getBearer, sanitizeErrorBody } from "./auth.js";
|
|
6
|
+
import { lookupIdem, recordIdem } from "./idempotency.js";
|
|
7
|
+
export function classifyAccessFault(status) {
|
|
8
|
+
if (status === 401)
|
|
9
|
+
return "auth";
|
|
10
|
+
if (status === 403)
|
|
11
|
+
return "whitelist";
|
|
12
|
+
return "network"; // status 0 / connect failure
|
|
13
|
+
}
|
|
14
|
+
function reqId() {
|
|
15
|
+
return randomBytes(6).toString("hex");
|
|
16
|
+
}
|
|
17
|
+
async function doFetch(args, accessToken, fetchImpl) {
|
|
18
|
+
const params = new URLSearchParams({ tenantId: args.store.tenantId, ...(args.query ?? {}) });
|
|
19
|
+
const url = `${apiBaseFor(args.store.environment)}/api/v1/${args.path}?${params.toString()}`;
|
|
20
|
+
const headers = { Authorization: `Bearer ${accessToken}`, Accept: "application/json" };
|
|
21
|
+
let bodyStr;
|
|
22
|
+
if (args.body !== undefined) {
|
|
23
|
+
headers["Content-Type"] = "application/json";
|
|
24
|
+
bodyStr = JSON.stringify({ tenantId: args.store.tenantId, ...args.body });
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const res = await fetchImpl(url, { method: args.method, headers, body: bodyStr });
|
|
28
|
+
return { ok: res.ok, status: res.status, text: await res.text() };
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
// connect-level failure → network access-fault
|
|
32
|
+
process.stderr.write(`[joblogic] op=access-fault kind=network tool=${args.tool} entity=${args.entity} detail=${err.message}\n`);
|
|
33
|
+
throw new Error(`access-fault kind=network: ${err.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** A read or generic call. Performs one silent re-acquire on a 401. */
|
|
37
|
+
export async function jlRequest(args, opts = {}) {
|
|
38
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
39
|
+
const id = reqId();
|
|
40
|
+
const isWrite = args.method === "POST";
|
|
41
|
+
process.stderr.write(isWrite
|
|
42
|
+
? `[joblogic] op=mutation reqId=${id} tool=${args.tool} entity=${args.entity} verb=update\n`
|
|
43
|
+
: `[joblogic] op=request reqId=${id} tool=${args.tool} entity=${args.entity}\n`);
|
|
44
|
+
let bearer = await getBearer(args.store, args.accountId, { fetchImpl });
|
|
45
|
+
const started = Date.now();
|
|
46
|
+
let res = await doFetch(args, bearer, fetchImpl);
|
|
47
|
+
if (res.status === 401) {
|
|
48
|
+
bearer = await getBearer(args.store, args.accountId, { force: true, fetchImpl });
|
|
49
|
+
res = await doFetch(args, bearer, fetchImpl);
|
|
50
|
+
}
|
|
51
|
+
const ms = Date.now() - started;
|
|
52
|
+
if (!res.ok) {
|
|
53
|
+
if (res.status === 401 || res.status === 403) {
|
|
54
|
+
process.stderr.write(`[joblogic] op=access-fault kind=${classifyAccessFault(res.status)} tool=${args.tool} entity=${args.entity}\n`);
|
|
55
|
+
}
|
|
56
|
+
process.stderr.write(`[joblogic] op=response reqId=${id} status=${res.status} ms=${ms} rows=-\n`);
|
|
57
|
+
throw new Error(`JobLogic ${args.method} ${args.path} ${res.status}: ${sanitizeErrorBody(res.text)}`);
|
|
58
|
+
}
|
|
59
|
+
let parsed;
|
|
60
|
+
try {
|
|
61
|
+
parsed = JSON.parse(res.text);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
throw new Error(`JobLogic ${args.path} non-JSON: ${res.text}`);
|
|
65
|
+
}
|
|
66
|
+
const data = parsed.data;
|
|
67
|
+
const rows = Array.isArray(data) ? data.length : "-";
|
|
68
|
+
process.stderr.write(`[joblogic] op=response reqId=${id} status=${res.status} ms=${ms} rows=${rows}\n`);
|
|
69
|
+
return parsed;
|
|
70
|
+
}
|
|
71
|
+
export async function jlCreate(args, opts = {}) {
|
|
72
|
+
const id = reqId();
|
|
73
|
+
const hit = lookupIdem(args.platformRoot, args.accountId, args.idemKey);
|
|
74
|
+
if (hit) {
|
|
75
|
+
process.stderr.write(`[joblogic] op=idem-hit reqId=${id} tool=${args.tool} existingId=${hit.recordId}\n`);
|
|
76
|
+
return { idempotent: true, id: hit.recordId, entity: hit.entity };
|
|
77
|
+
}
|
|
78
|
+
const result = await jlRequest({
|
|
79
|
+
store: args.store,
|
|
80
|
+
accountId: args.accountId,
|
|
81
|
+
method: "POST",
|
|
82
|
+
path: args.path,
|
|
83
|
+
entity: args.entity,
|
|
84
|
+
tool: args.tool,
|
|
85
|
+
query: args.query,
|
|
86
|
+
body: args.body,
|
|
87
|
+
}, opts);
|
|
88
|
+
const writtenId = extractId(result, args.idField);
|
|
89
|
+
if (!writtenId) {
|
|
90
|
+
// A 2xx with no extractable record id means the ledger cannot be written, so
|
|
91
|
+
// a retry of the same idemKey would duplicate. Fail loudly (the response
|
|
92
|
+
// shape / idField is provisional until UAT-confirmed) rather than silently
|
|
93
|
+
// leaving an idempotency hole.
|
|
94
|
+
process.stderr.write(`[joblogic] op=idem-record-fail reqId=${id} tool=${args.tool} entity=${args.entity} reason=id-unextractable\n`);
|
|
95
|
+
throw new Error(`${args.tool}: create returned success but no '${args.idField ?? "id"}' could be extracted from the response — a retry would NOT be idempotent. Confirm the response shape / idField against UAT.`);
|
|
96
|
+
}
|
|
97
|
+
recordIdem(args.platformRoot, args.accountId, args.idemKey, args.entity, writtenId);
|
|
98
|
+
process.stderr.write(`[joblogic] op=response reqId=${id} status=created id=${writtenId}\n`);
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
function extractId(result, idField = "id") {
|
|
102
|
+
const r = result;
|
|
103
|
+
const v = r?.[idField] ?? r?.data?.[idField];
|
|
104
|
+
return v == null ? null : String(v);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface IdemRecord {
|
|
2
|
+
entity: string;
|
|
3
|
+
recordId: string;
|
|
4
|
+
ts: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function lookupIdem(platformRoot: string, accountId: string, idemKey: string): IdemRecord | null;
|
|
7
|
+
export declare function recordIdem(platformRoot: string, accountId: string, idemKey: string, entity: string, recordId: string): void;
|
|
8
|
+
//# sourceMappingURL=idempotency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/lib/idempotency.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ;AAUD,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAatG;AAED,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,IAAI,CAKN"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Local idempotency ledger. JobLogic exposes no idempotency header, so a create
|
|
2
|
+
// retry (tool retry, or a write whose response was lost to a timeout) would
|
|
3
|
+
// duplicate. Each create computes/accepts an idemKey; the ledger maps it to the
|
|
4
|
+
// record id JobLogic returned. A hit short-circuits the send entirely.
|
|
5
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { accountSecretsDir } from "./secrets.js";
|
|
8
|
+
/** idemKey filename safety — no path fragments. */
|
|
9
|
+
const KEY_RE = /^[A-Za-z0-9_.:-]+$/;
|
|
10
|
+
function ledgerDir(platformRoot, accountId) {
|
|
11
|
+
return join(accountSecretsDir(platformRoot, accountId), "joblogic-idem");
|
|
12
|
+
}
|
|
13
|
+
function ledgerPath(platformRoot, accountId, idemKey) {
|
|
14
|
+
if (!KEY_RE.test(idemKey))
|
|
15
|
+
throw new Error(`invalid idemKey: ${JSON.stringify(idemKey)}`);
|
|
16
|
+
return join(ledgerDir(platformRoot, accountId), `${idemKey}.json`);
|
|
17
|
+
}
|
|
18
|
+
export function lookupIdem(platformRoot, accountId, idemKey) {
|
|
19
|
+
let file;
|
|
20
|
+
try {
|
|
21
|
+
file = ledgerPath(platformRoot, accountId, idemKey);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
if (!existsSync(file))
|
|
27
|
+
return null;
|
|
28
|
+
try {
|
|
29
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export function recordIdem(platformRoot, accountId, idemKey, entity, recordId) {
|
|
36
|
+
const file = ledgerPath(platformRoot, accountId, idemKey);
|
|
37
|
+
mkdirSync(ledgerDir(platformRoot, accountId), { recursive: true });
|
|
38
|
+
const rec = { entity, recordId, ts: Date.now() };
|
|
39
|
+
writeFileSync(file, JSON.stringify(rec), { mode: 0o600 });
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=idempotency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/lib/idempotency.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAChF,uEAAuE;AACvE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,mDAAmD;AACnD,MAAM,MAAM,GAAG,oBAAoB,CAAC;AAQpC,SAAS,SAAS,CAAC,YAAoB,EAAE,SAAiB;IACxD,OAAO,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,eAAe,CAAC,CAAC;AAC3E,CAAC;AACD,SAAS,UAAU,CAAC,YAAoB,EAAE,SAAiB,EAAE,OAAe;IAC1E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1F,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,OAAO,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,YAAoB,EAAE,SAAiB,EAAE,OAAe;IACjF,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,UAAU,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAe,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,YAAoB,EACpB,SAAiB,EACjB,OAAe,EACf,MAAc,EACd,QAAgB;IAEhB,MAAM,IAAI,GAAG,UAAU,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC1D,SAAS,CAAC,SAAS,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,MAAM,GAAG,GAAe,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IAC7D,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type JlEnvironment = "uat" | "production";
|
|
2
|
+
export interface JlStore {
|
|
3
|
+
clientId: string;
|
|
4
|
+
clientSecret: string;
|
|
5
|
+
/** Company tenant id — required on every JobLogic API call (tenant-scoped credential). */
|
|
6
|
+
tenantId: string;
|
|
7
|
+
environment: JlEnvironment;
|
|
8
|
+
/** Sender phone (E.164) → JobLogic engineer id, for write attribution. Config, not a secret. */
|
|
9
|
+
engineerMap: Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
export declare function accountSecretsDir(platformRoot: string, accountId: string): string;
|
|
12
|
+
export declare function readStore(platformRoot: string, accountId: string): JlStore | null;
|
|
13
|
+
export declare function setCredentials(platformRoot: string, accountId: string, creds: {
|
|
14
|
+
clientId: string;
|
|
15
|
+
clientSecret: string;
|
|
16
|
+
tenantId: string;
|
|
17
|
+
environment: JlEnvironment;
|
|
18
|
+
}): void;
|
|
19
|
+
export declare function setEngineerMap(platformRoot: string, accountId: string, entries: Record<string, string>): void;
|
|
20
|
+
export declare function resolveEngineer(store: JlStore, senderPhone: string): string | null;
|
|
21
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,YAAY,CAAC;AAEjD,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,aAAa,CAAC;IAC3B,gGAAgG;IAChG,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAKD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjF;AAKD,wBAAgB,SAAS,CAAC,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAUjF;AAOD,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,aAAa,CAAA;CAAE,GAC9F,IAAI,CAGN;AAED,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,IAAI,CAIN;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAElF"}
|