p1-polymorph-studio 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/314-lex.js +2 -0
- package/dist/chunk-BCH2RATL.js +817 -0
- package/dist/chunk-BCH2RATL.js.map +1 -0
- package/dist/chunk-HGZJ53NR.cjs +817 -0
- package/dist/chunk-HGZJ53NR.cjs.map +1 -0
- package/dist/cli/index.cjs +423 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +2 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +423 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.cjs +59 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +895 -0
- package/dist/index.d.ts +895 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/utils/errors.ts
|
|
2
|
+
var LexApiError = class extends Error {
|
|
3
|
+
constructor(message, statusCode, body) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.statusCode = statusCode;
|
|
6
|
+
this.body = body;
|
|
7
|
+
this.name = "LexApiError";
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
var LexValidationError = class extends Error {
|
|
11
|
+
constructor(message, errors) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.errors = errors;
|
|
14
|
+
this.name = "LexValidationError";
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var LexConfigError = class extends Error {
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "LexConfigError";
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/utils/api.ts
|
|
25
|
+
function toSnakeCase(str) {
|
|
26
|
+
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
27
|
+
}
|
|
28
|
+
function toCamelCase(str) {
|
|
29
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
30
|
+
}
|
|
31
|
+
function convertKeys(obj, converter) {
|
|
32
|
+
if (obj === null || obj === void 0) return obj;
|
|
33
|
+
if (Array.isArray(obj)) return obj.map((item) => convertKeys(item, converter));
|
|
34
|
+
if (typeof obj === "object") {
|
|
35
|
+
const result = {};
|
|
36
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
37
|
+
result[converter(key)] = convertKeys(value, converter);
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
return obj;
|
|
42
|
+
}
|
|
43
|
+
function toApiPayload(obj) {
|
|
44
|
+
return convertKeys(obj, toSnakeCase);
|
|
45
|
+
}
|
|
46
|
+
function fromApiResponse(obj) {
|
|
47
|
+
return convertKeys(obj, toCamelCase);
|
|
48
|
+
}
|
|
49
|
+
function createApiClient(options) {
|
|
50
|
+
const { baseUrl, token, projectId } = options;
|
|
51
|
+
const fetchFn = _nullishCoalesce(options.fetch, () => ( globalThis.fetch));
|
|
52
|
+
async function request(method, path, body, params) {
|
|
53
|
+
const url = new URL(path, baseUrl);
|
|
54
|
+
url.searchParams.set("project_id", projectId);
|
|
55
|
+
if (params) {
|
|
56
|
+
for (const [key, value] of Object.entries(params)) {
|
|
57
|
+
url.searchParams.set(key, value);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const headers = {
|
|
61
|
+
"Authorization": `Bearer ${token}`,
|
|
62
|
+
"Content-Type": "application/json"
|
|
63
|
+
};
|
|
64
|
+
const init = { method, headers };
|
|
65
|
+
if (body !== void 0) {
|
|
66
|
+
init.body = JSON.stringify(toApiPayload(body));
|
|
67
|
+
}
|
|
68
|
+
const response = await fetchFn(url.toString(), init);
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
let errorBody;
|
|
71
|
+
try {
|
|
72
|
+
errorBody = await response.json();
|
|
73
|
+
} catch (e2) {
|
|
74
|
+
errorBody = await response.text();
|
|
75
|
+
}
|
|
76
|
+
throw new LexApiError(
|
|
77
|
+
`API request failed: ${method} ${path} \u2192 ${response.status}`,
|
|
78
|
+
response.status,
|
|
79
|
+
errorBody
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
if (response.status === 204) return void 0;
|
|
83
|
+
const data = await response.json();
|
|
84
|
+
return fromApiResponse(data);
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
get: (path, params) => request("GET", path, void 0, params),
|
|
88
|
+
post: (path, body) => request("POST", path, body),
|
|
89
|
+
put: (path, body) => request("PUT", path, body),
|
|
90
|
+
del: (path) => request("DELETE", path)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/client/kuds.ts
|
|
95
|
+
var _promises = require('fs/promises');
|
|
96
|
+
|
|
97
|
+
// src/types/registry.ts
|
|
98
|
+
var _zod = require('zod');
|
|
99
|
+
|
|
100
|
+
// src/types/kud.ts
|
|
101
|
+
|
|
102
|
+
var KUDFieldTypeSchema = _zod.z.enum([
|
|
103
|
+
"string",
|
|
104
|
+
"text",
|
|
105
|
+
"number",
|
|
106
|
+
"boolean",
|
|
107
|
+
"image",
|
|
108
|
+
"link",
|
|
109
|
+
"array",
|
|
110
|
+
"object"
|
|
111
|
+
]);
|
|
112
|
+
var KUDFieldDefSchema = _zod.z.lazy(
|
|
113
|
+
() => _zod.z.object({
|
|
114
|
+
type: KUDFieldTypeSchema,
|
|
115
|
+
required: _zod.z.boolean().optional(),
|
|
116
|
+
description: _zod.z.string().optional(),
|
|
117
|
+
items: KUDFieldDefSchema.optional(),
|
|
118
|
+
properties: _zod.z.record(_zod.z.string(), KUDFieldDefSchema).optional()
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
var KUDSchema = _zod.z.object({
|
|
122
|
+
id: _zod.z.string().uuid(),
|
|
123
|
+
projectId: _zod.z.string(),
|
|
124
|
+
type: _zod.z.string(),
|
|
125
|
+
label: _zod.z.string().nullable().optional(),
|
|
126
|
+
version: _zod.z.number().int().default(1),
|
|
127
|
+
schema: _zod.z.record(_zod.z.string(), KUDFieldDefSchema),
|
|
128
|
+
defaultKuiId: _zod.z.string().uuid().nullable().optional(),
|
|
129
|
+
metadata: _zod.z.record(_zod.z.string(), _zod.z.unknown()).nullable().optional(),
|
|
130
|
+
createdAt: _zod.z.string(),
|
|
131
|
+
updatedAt: _zod.z.string()
|
|
132
|
+
});
|
|
133
|
+
var CreateKUDInputSchema = _zod.z.object({
|
|
134
|
+
type: _zod.z.string().min(1),
|
|
135
|
+
label: _zod.z.string().optional(),
|
|
136
|
+
schema: _zod.z.record(_zod.z.string(), KUDFieldDefSchema),
|
|
137
|
+
metadata: _zod.z.record(_zod.z.string(), _zod.z.unknown()).optional()
|
|
138
|
+
});
|
|
139
|
+
var UpdateKUDInputSchema = _zod.z.object({
|
|
140
|
+
label: _zod.z.string().optional(),
|
|
141
|
+
schema: _zod.z.record(_zod.z.string(), KUDFieldDefSchema).optional(),
|
|
142
|
+
metadata: _zod.z.record(_zod.z.string(), _zod.z.unknown()).optional()
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// src/types/registry.ts
|
|
146
|
+
var KudRegistryEntrySchema = _zod.z.object({
|
|
147
|
+
type: _zod.z.string(),
|
|
148
|
+
label: _zod.z.string().optional(),
|
|
149
|
+
version: _zod.z.number().int().default(1),
|
|
150
|
+
schema: _zod.z.record(_zod.z.string(), KUDFieldDefSchema),
|
|
151
|
+
componentPath: _zod.z.string().optional(),
|
|
152
|
+
metadata: _zod.z.record(_zod.z.string(), _zod.z.unknown()).optional()
|
|
153
|
+
});
|
|
154
|
+
var KudRegistrySchema = _zod.z.object({
|
|
155
|
+
version: _zod.z.number().int().default(1),
|
|
156
|
+
projectId: _zod.z.string(),
|
|
157
|
+
generatedAt: _zod.z.string(),
|
|
158
|
+
kuds: _zod.z.array(KudRegistryEntrySchema)
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// src/utils/diff.ts
|
|
162
|
+
function deepEqual(a, b) {
|
|
163
|
+
if (a === b) return true;
|
|
164
|
+
if (a === null || b === null) return false;
|
|
165
|
+
if (typeof a !== typeof b) return false;
|
|
166
|
+
if (typeof a !== "object") return false;
|
|
167
|
+
const aObj = a;
|
|
168
|
+
const bObj = b;
|
|
169
|
+
const aKeys = Object.keys(aObj);
|
|
170
|
+
const bKeys = Object.keys(bObj);
|
|
171
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
172
|
+
return aKeys.every((key) => deepEqual(aObj[key], bObj[key]));
|
|
173
|
+
}
|
|
174
|
+
function diffRegistryVsDatabase(registry, dbKuds) {
|
|
175
|
+
const dbByType = new Map(dbKuds.map((kud) => [kud.type, kud]));
|
|
176
|
+
const registryTypes = new Set(registry.map((e) => e.type));
|
|
177
|
+
const toCreate = [];
|
|
178
|
+
const toUpdate = [];
|
|
179
|
+
const unchanged = [];
|
|
180
|
+
for (const entry of registry) {
|
|
181
|
+
const existing = dbByType.get(entry.type);
|
|
182
|
+
if (!existing) {
|
|
183
|
+
toCreate.push(entry);
|
|
184
|
+
} else if (!deepEqual(entry.schema, existing.schema)) {
|
|
185
|
+
toUpdate.push({ entry, existingId: existing.id });
|
|
186
|
+
} else {
|
|
187
|
+
unchanged.push(existing);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const toDelete = dbKuds.filter((kud) => !registryTypes.has(kud.type));
|
|
191
|
+
return { toCreate, toUpdate, toDelete, unchanged };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/client/kuds.ts
|
|
195
|
+
function createKudsClient(api, projectId) {
|
|
196
|
+
return {
|
|
197
|
+
async list() {
|
|
198
|
+
return api.get("/kuds");
|
|
199
|
+
},
|
|
200
|
+
async getByType(type) {
|
|
201
|
+
const kuds = await api.get("/kuds", { type });
|
|
202
|
+
return _nullishCoalesce(kuds[0], () => ( null));
|
|
203
|
+
},
|
|
204
|
+
async create(input) {
|
|
205
|
+
return api.post("/kuds", input);
|
|
206
|
+
},
|
|
207
|
+
async update(id, input) {
|
|
208
|
+
return api.put(`/kuds/${id}`, input);
|
|
209
|
+
},
|
|
210
|
+
async delete(id) {
|
|
211
|
+
await api.del(`/kuds/${id}`);
|
|
212
|
+
},
|
|
213
|
+
async syncFromRegistry(registryPath) {
|
|
214
|
+
const raw = await _promises.readFile.call(void 0, registryPath, "utf-8");
|
|
215
|
+
const registry = KudRegistrySchema.parse(JSON.parse(raw));
|
|
216
|
+
const dbKuds = await api.get("/kuds");
|
|
217
|
+
const diff = diffRegistryVsDatabase(registry.kuds, dbKuds);
|
|
218
|
+
for (const entry of diff.toCreate) {
|
|
219
|
+
await api.post("/kuds", {
|
|
220
|
+
type: entry.type,
|
|
221
|
+
label: entry.label,
|
|
222
|
+
schema: entry.schema,
|
|
223
|
+
metadata: entry.metadata
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
for (const { entry, existingId } of diff.toUpdate) {
|
|
227
|
+
await api.put(`/kuds/${existingId}`, {
|
|
228
|
+
schema: entry.schema,
|
|
229
|
+
label: entry.label,
|
|
230
|
+
metadata: entry.metadata
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
for (const kud of diff.toDelete) {
|
|
234
|
+
await api.del(`/kuds/${kud.id}`);
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
created: diff.toCreate.length,
|
|
238
|
+
updated: diff.toUpdate.length,
|
|
239
|
+
deleted: diff.toDelete.length,
|
|
240
|
+
unchanged: diff.unchanged.length
|
|
241
|
+
};
|
|
242
|
+
},
|
|
243
|
+
async syncToRegistry(registryPath) {
|
|
244
|
+
const dbKuds = await api.get("/kuds");
|
|
245
|
+
const registry = {
|
|
246
|
+
version: 1,
|
|
247
|
+
projectId,
|
|
248
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
249
|
+
kuds: dbKuds.map((kud) => ({
|
|
250
|
+
type: kud.type,
|
|
251
|
+
label: _nullishCoalesce(kud.label, () => ( void 0)),
|
|
252
|
+
version: kud.version,
|
|
253
|
+
schema: kud.schema,
|
|
254
|
+
metadata: _nullishCoalesce(kud.metadata, () => ( void 0))
|
|
255
|
+
}))
|
|
256
|
+
};
|
|
257
|
+
await _promises.writeFile.call(void 0, registryPath, JSON.stringify(registry, null, 2) + "\n", "utf-8");
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/utils/cosine.ts
|
|
263
|
+
function cosineSimilarity(a, b) {
|
|
264
|
+
if (a.length !== b.length) {
|
|
265
|
+
throw new Error(`Vector length mismatch: ${a.length} vs ${b.length}`);
|
|
266
|
+
}
|
|
267
|
+
let dot = 0;
|
|
268
|
+
let magA = 0;
|
|
269
|
+
let magB = 0;
|
|
270
|
+
for (let i = 0; i < a.length; i++) {
|
|
271
|
+
dot += a[i] * b[i];
|
|
272
|
+
magA += a[i] * a[i];
|
|
273
|
+
magB += b[i] * b[i];
|
|
274
|
+
}
|
|
275
|
+
const magnitude = Math.sqrt(magA) * Math.sqrt(magB);
|
|
276
|
+
if (magnitude === 0) return 0;
|
|
277
|
+
return dot / magnitude;
|
|
278
|
+
}
|
|
279
|
+
function blendedScore(candidatePosition, candidateVelocity, query) {
|
|
280
|
+
const positionScore = cosineSimilarity(candidatePosition, query.queryVector);
|
|
281
|
+
const weight = _nullishCoalesce(query.velocityWeight, () => ( 0.3));
|
|
282
|
+
if (!query.queryVelocity || !candidateVelocity || weight === 0) {
|
|
283
|
+
return { score: positionScore, positionScore, velocityScore: 0 };
|
|
284
|
+
}
|
|
285
|
+
const velocityScore = cosineSimilarity(candidateVelocity, query.queryVelocity);
|
|
286
|
+
const score = (1 - weight) * positionScore + weight * velocityScore;
|
|
287
|
+
return { score, positionScore, velocityScore };
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/client/kuis.ts
|
|
291
|
+
function createKuisClient(api, _projectId) {
|
|
292
|
+
return {
|
|
293
|
+
async list(filter) {
|
|
294
|
+
const params = {};
|
|
295
|
+
if (_optionalChain([filter, 'optionalAccess', _2 => _2.kudType])) params.kud_type = filter.kudType;
|
|
296
|
+
if (_optionalChain([filter, 'optionalAccess', _3 => _3.locale])) params.locale = filter.locale;
|
|
297
|
+
if (_optionalChain([filter, 'optionalAccess', _4 => _4.status])) params.status = filter.status;
|
|
298
|
+
if (_optionalChain([filter, 'optionalAccess', _5 => _5.intentStage])) params.intent_stage = filter.intentStage;
|
|
299
|
+
return api.get("/kuis", params);
|
|
300
|
+
},
|
|
301
|
+
async resolve(input) {
|
|
302
|
+
try {
|
|
303
|
+
return await api.post("/kuis/resolve", input);
|
|
304
|
+
} catch (err) {
|
|
305
|
+
if (err instanceof LexApiError && err.statusCode === 404) {
|
|
306
|
+
const kuis = await api.get("/kuis", {
|
|
307
|
+
kud_type: input.kudType,
|
|
308
|
+
locale: input.locale,
|
|
309
|
+
status: "published"
|
|
310
|
+
});
|
|
311
|
+
if (kuis.length === 0) return null;
|
|
312
|
+
let bestKui = null;
|
|
313
|
+
let bestScore = -Infinity;
|
|
314
|
+
for (const kui of kuis) {
|
|
315
|
+
const { score } = blendedScore(
|
|
316
|
+
kui.intentAffinity,
|
|
317
|
+
kui.intentVelocity,
|
|
318
|
+
{
|
|
319
|
+
queryVector: input.intentVector,
|
|
320
|
+
queryVelocity: input.intentVelocity,
|
|
321
|
+
velocityWeight: input.velocityWeight
|
|
322
|
+
}
|
|
323
|
+
);
|
|
324
|
+
if (score > bestScore || score === bestScore && kui.priority > (_nullishCoalesce(_optionalChain([bestKui, 'optionalAccess', _6 => _6.priority]), () => ( 0)))) {
|
|
325
|
+
bestScore = score;
|
|
326
|
+
bestKui = kui;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return bestKui;
|
|
330
|
+
}
|
|
331
|
+
throw err;
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
async create(input) {
|
|
335
|
+
return api.post("/kuis", input);
|
|
336
|
+
},
|
|
337
|
+
async update(id, input) {
|
|
338
|
+
return api.put(`/kuis/${id}`, input);
|
|
339
|
+
},
|
|
340
|
+
async publish(id) {
|
|
341
|
+
return api.put(`/kuis/${id}`, { status: "published" });
|
|
342
|
+
},
|
|
343
|
+
async archive(id) {
|
|
344
|
+
return api.put(`/kuis/${id}`, { status: "archived" });
|
|
345
|
+
},
|
|
346
|
+
async bulkImport(items) {
|
|
347
|
+
let created = 0;
|
|
348
|
+
const errors = [];
|
|
349
|
+
for (let i = 0; i < items.length; i++) {
|
|
350
|
+
try {
|
|
351
|
+
await api.post("/kuis", items[i]);
|
|
352
|
+
created++;
|
|
353
|
+
} catch (err) {
|
|
354
|
+
errors.push({
|
|
355
|
+
index: i,
|
|
356
|
+
error: err instanceof Error ? err.message : String(err)
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return { created, errors };
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// src/client/layouts.ts
|
|
366
|
+
function createLayoutsClient(api, _projectId) {
|
|
367
|
+
return {
|
|
368
|
+
async get(pageId, locale) {
|
|
369
|
+
const params = {};
|
|
370
|
+
if (locale) params.locale = locale;
|
|
371
|
+
return api.get(`/layouts/${pageId}`, params);
|
|
372
|
+
},
|
|
373
|
+
async update(pageId, locale, input) {
|
|
374
|
+
return api.put(`/layouts/${pageId}`, { locale, ...input });
|
|
375
|
+
},
|
|
376
|
+
async resolve(pageId, opts) {
|
|
377
|
+
try {
|
|
378
|
+
return await api.post(`/layouts/${pageId}/resolve`, {
|
|
379
|
+
locale: _nullishCoalesce(opts.locale, () => ( "en")),
|
|
380
|
+
intentVector: opts.intentVector,
|
|
381
|
+
intentVelocity: opts.intentVelocity,
|
|
382
|
+
velocityWeight: opts.velocityWeight
|
|
383
|
+
});
|
|
384
|
+
} catch (err) {
|
|
385
|
+
if (err instanceof LexApiError && err.statusCode === 404) {
|
|
386
|
+
const locale = _nullishCoalesce(opts.locale, () => ( "en"));
|
|
387
|
+
const layout = await this.get(pageId, locale);
|
|
388
|
+
const resolvedSlots = await Promise.all(
|
|
389
|
+
layout.slots.map(async (slot) => {
|
|
390
|
+
const kuis = await api.get("/kuis", {
|
|
391
|
+
kud_type: slot.kudId,
|
|
392
|
+
locale,
|
|
393
|
+
status: "published"
|
|
394
|
+
});
|
|
395
|
+
let bestKui = null;
|
|
396
|
+
let bestScore = -Infinity;
|
|
397
|
+
for (const kui of kuis) {
|
|
398
|
+
const { score } = blendedScore(
|
|
399
|
+
kui.intentAffinity,
|
|
400
|
+
kui.intentVelocity,
|
|
401
|
+
{
|
|
402
|
+
queryVector: opts.intentVector,
|
|
403
|
+
queryVelocity: opts.intentVelocity,
|
|
404
|
+
velocityWeight: opts.velocityWeight
|
|
405
|
+
}
|
|
406
|
+
);
|
|
407
|
+
if (score > bestScore || score === bestScore && kui.priority > (_nullishCoalesce(_optionalChain([bestKui, 'optionalAccess', _7 => _7.priority]), () => ( 0)))) {
|
|
408
|
+
bestScore = score;
|
|
409
|
+
bestKui = kui;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return {
|
|
413
|
+
slotId: slot.slotId,
|
|
414
|
+
kui: bestKui,
|
|
415
|
+
score: bestScore
|
|
416
|
+
};
|
|
417
|
+
})
|
|
418
|
+
);
|
|
419
|
+
return {
|
|
420
|
+
pageId,
|
|
421
|
+
slots: resolvedSlots.filter((s) => s.kui !== null)
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
throw err;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// src/client/tokens.ts
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
// src/utils/css-parser.ts
|
|
434
|
+
function classifyToken(name) {
|
|
435
|
+
if (name.startsWith("--color-") || name.startsWith("--tw-color-")) return "colors";
|
|
436
|
+
if (name.startsWith("--font-") || name.startsWith("--tw-font-")) return "typography";
|
|
437
|
+
if (name.startsWith("--spacing-") || name.startsWith("--tw-spacing-")) return "spacing";
|
|
438
|
+
if (name.startsWith("--radius-") || name.startsWith("--tw-radius-")) return "borderRadius";
|
|
439
|
+
if (name.startsWith("--shadow-") || name.startsWith("--tw-shadow-")) return "shadows";
|
|
440
|
+
return "other";
|
|
441
|
+
}
|
|
442
|
+
function stripPrefix(name) {
|
|
443
|
+
return name.replace(/^--(?:tw-)?/, "");
|
|
444
|
+
}
|
|
445
|
+
function extractTokensFromCSS(cssContent) {
|
|
446
|
+
const tokens = [];
|
|
447
|
+
const rootBlockRegex = /:root\s*\{([^}]+)\}/g;
|
|
448
|
+
let match;
|
|
449
|
+
while ((match = rootBlockRegex.exec(cssContent)) !== null) {
|
|
450
|
+
const block = match[1];
|
|
451
|
+
parseCustomProperties(block, tokens);
|
|
452
|
+
}
|
|
453
|
+
const themeBlockRegex = /@theme\s*\{([^}]+)\}/g;
|
|
454
|
+
while ((match = themeBlockRegex.exec(cssContent)) !== null) {
|
|
455
|
+
const block = match[1];
|
|
456
|
+
parseCustomProperties(block, tokens);
|
|
457
|
+
}
|
|
458
|
+
return tokens;
|
|
459
|
+
}
|
|
460
|
+
function parseCustomProperties(block, tokens) {
|
|
461
|
+
const propRegex = /(--[\w-]+)\s*:\s*([^;]+);/g;
|
|
462
|
+
let match;
|
|
463
|
+
while ((match = propRegex.exec(block)) !== null) {
|
|
464
|
+
const name = match[1];
|
|
465
|
+
const value = match[2].trim();
|
|
466
|
+
tokens.push({
|
|
467
|
+
collection: classifyToken(name),
|
|
468
|
+
name: stripPrefix(name),
|
|
469
|
+
value
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
function generateCSSFromTokens(tokens) {
|
|
474
|
+
const lines = [":root {"];
|
|
475
|
+
for (const token of tokens) {
|
|
476
|
+
const cssName = `--${token.name}`;
|
|
477
|
+
const value = _nullishCoalesce(token.valueLight, () => ( token.valueDark));
|
|
478
|
+
if (value !== null && value !== void 0) {
|
|
479
|
+
lines.push(` ${cssName}: ${String(value)};`);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
lines.push("}");
|
|
483
|
+
const darkTokens = tokens.filter((t) => t.valueDark !== null && t.valueDark !== void 0);
|
|
484
|
+
if (darkTokens.length > 0) {
|
|
485
|
+
lines.push("");
|
|
486
|
+
lines.push("@media (prefers-color-scheme: dark) {");
|
|
487
|
+
lines.push(" :root {");
|
|
488
|
+
for (const token of darkTokens) {
|
|
489
|
+
lines.push(` --${token.name}: ${String(token.valueDark)};`);
|
|
490
|
+
}
|
|
491
|
+
lines.push(" }");
|
|
492
|
+
lines.push("}");
|
|
493
|
+
}
|
|
494
|
+
return lines.join("\n") + "\n";
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
// src/client/tokens.ts
|
|
498
|
+
function createTokensClient(api, _projectId) {
|
|
499
|
+
return {
|
|
500
|
+
async pushFromCode(cssPath) {
|
|
501
|
+
const css = await _promises.readFile.call(void 0, cssPath, "utf-8");
|
|
502
|
+
const extracted = extractTokensFromCSS(css);
|
|
503
|
+
let upserted = 0;
|
|
504
|
+
for (const token of extracted) {
|
|
505
|
+
await api.post("/tokens", {
|
|
506
|
+
collection: token.collection,
|
|
507
|
+
name: token.name,
|
|
508
|
+
valueLight: token.value
|
|
509
|
+
});
|
|
510
|
+
upserted++;
|
|
511
|
+
}
|
|
512
|
+
return { upserted };
|
|
513
|
+
},
|
|
514
|
+
async pullToCode(cssPath) {
|
|
515
|
+
const tokens = await api.get("/tokens");
|
|
516
|
+
const css = generateCSSFromTokens(tokens);
|
|
517
|
+
await _promises.writeFile.call(void 0, cssPath, css, "utf-8");
|
|
518
|
+
},
|
|
519
|
+
async pullFromFigma(opts) {
|
|
520
|
+
const url = `https://api.figma.com/v1/files/${opts.fileKey}/variables/local`;
|
|
521
|
+
const response = await fetch(url, {
|
|
522
|
+
headers: { "X-Figma-Token": opts.figmaToken }
|
|
523
|
+
});
|
|
524
|
+
if (!response.ok) {
|
|
525
|
+
throw new Error(`Figma API error: ${response.status} ${response.statusText}`);
|
|
526
|
+
}
|
|
527
|
+
const data = await response.json();
|
|
528
|
+
let synced = 0;
|
|
529
|
+
const variables = Object.values(data.meta.variables);
|
|
530
|
+
for (const variable of variables) {
|
|
531
|
+
const collection = variable.resolvedType.toLowerCase() === "color" ? "colors" : "other";
|
|
532
|
+
const modes = Object.entries(variable.valuesByMode);
|
|
533
|
+
const lightValue = _optionalChain([modes, 'access', _8 => _8[0], 'optionalAccess', _9 => _9[1]]);
|
|
534
|
+
const darkValue = _optionalChain([modes, 'access', _10 => _10[1], 'optionalAccess', _11 => _11[1]]);
|
|
535
|
+
await api.post("/tokens", {
|
|
536
|
+
collection,
|
|
537
|
+
name: variable.name,
|
|
538
|
+
valueLight: lightValue,
|
|
539
|
+
valueDark: darkValue,
|
|
540
|
+
figmaVariableId: variable.id
|
|
541
|
+
});
|
|
542
|
+
synced++;
|
|
543
|
+
}
|
|
544
|
+
return { synced };
|
|
545
|
+
},
|
|
546
|
+
async exportDTCG() {
|
|
547
|
+
const tokens = await api.get("/tokens");
|
|
548
|
+
const dtcg = {};
|
|
549
|
+
for (const token of tokens) {
|
|
550
|
+
const parts = token.name.split("/");
|
|
551
|
+
let current = dtcg;
|
|
552
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
553
|
+
if (!current[parts[i]]) current[parts[i]] = {};
|
|
554
|
+
current = current[parts[i]];
|
|
555
|
+
}
|
|
556
|
+
const leafName = parts[parts.length - 1];
|
|
557
|
+
current[leafName] = {
|
|
558
|
+
$value: token.valueLight,
|
|
559
|
+
$type: token.collection === "colors" ? "color" : token.collection,
|
|
560
|
+
...token.valueDark ? { $extensions: { "com.figma": { dark: token.valueDark } } } : {}
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
return dtcg;
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// src/client/config.ts
|
|
569
|
+
|
|
570
|
+
var _fs = require('fs');
|
|
571
|
+
function createConfigClient(api, projectId) {
|
|
572
|
+
return {
|
|
573
|
+
async generate(outputPath = "314-lex.config.json") {
|
|
574
|
+
let existing = {};
|
|
575
|
+
try {
|
|
576
|
+
const raw = await _promises.readFile.call(void 0, outputPath, "utf-8");
|
|
577
|
+
existing = JSON.parse(raw);
|
|
578
|
+
} catch (e3) {
|
|
579
|
+
}
|
|
580
|
+
const config = {
|
|
581
|
+
$schema: "https://unpkg.com/@314-lex/sdk/schema/config.json",
|
|
582
|
+
version: 2,
|
|
583
|
+
name: _nullishCoalesce(existing.name, () => ( projectId)),
|
|
584
|
+
projectId: _nullishCoalesce(existing.projectId, () => ( projectId)),
|
|
585
|
+
tokens: existing.tokens,
|
|
586
|
+
kuds: existing.kuds,
|
|
587
|
+
figma: existing.figma,
|
|
588
|
+
api: _nullishCoalesce(existing.api, () => ( {
|
|
589
|
+
baseUrl: "env:POLYMORPH_BASE_URL",
|
|
590
|
+
token: "env:POLYMORPH_TOKEN",
|
|
591
|
+
routes: "/api/314-lex"
|
|
592
|
+
})),
|
|
593
|
+
github: existing.github
|
|
594
|
+
};
|
|
595
|
+
await _promises.writeFile.call(void 0, outputPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
596
|
+
},
|
|
597
|
+
async generateRegistry(outputPath = "kuds.registry.json") {
|
|
598
|
+
const dbKuds = await api.get("/kuds");
|
|
599
|
+
const registry = {
|
|
600
|
+
version: 1,
|
|
601
|
+
projectId,
|
|
602
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
603
|
+
kuds: dbKuds.map((kud) => ({
|
|
604
|
+
type: kud.type,
|
|
605
|
+
label: _nullishCoalesce(kud.label, () => ( void 0)),
|
|
606
|
+
version: kud.version,
|
|
607
|
+
schema: kud.schema,
|
|
608
|
+
metadata: _nullishCoalesce(kud.metadata, () => ( void 0))
|
|
609
|
+
}))
|
|
610
|
+
};
|
|
611
|
+
await _promises.writeFile.call(void 0, outputPath, JSON.stringify(registry, null, 2) + "\n", "utf-8");
|
|
612
|
+
},
|
|
613
|
+
watch(opts) {
|
|
614
|
+
const watchers = [];
|
|
615
|
+
for (const path of opts.paths) {
|
|
616
|
+
const watcher = _fs.watch.call(void 0, path, { recursive: true }, (_event, filename) => {
|
|
617
|
+
if (filename) {
|
|
618
|
+
opts.onChange(filename);
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
watchers.push(watcher);
|
|
622
|
+
}
|
|
623
|
+
return () => {
|
|
624
|
+
for (const watcher of watchers) {
|
|
625
|
+
watcher.close();
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// src/types/kui.ts
|
|
633
|
+
|
|
634
|
+
var IntentVectorSchema = _zod.z.tuple([
|
|
635
|
+
_zod.z.number(),
|
|
636
|
+
_zod.z.number(),
|
|
637
|
+
_zod.z.number(),
|
|
638
|
+
_zod.z.number(),
|
|
639
|
+
_zod.z.number()
|
|
640
|
+
]);
|
|
641
|
+
var KUIStatusSchema = _zod.z.enum(["draft", "published", "archived"]);
|
|
642
|
+
var KUISchema = _zod.z.object({
|
|
643
|
+
id: _zod.z.string().uuid(),
|
|
644
|
+
kudId: _zod.z.string().uuid(),
|
|
645
|
+
kudType: _zod.z.string(),
|
|
646
|
+
projectId: _zod.z.string(),
|
|
647
|
+
locale: _zod.z.string().default("en"),
|
|
648
|
+
intentAffinity: IntentVectorSchema,
|
|
649
|
+
intentVelocity: IntentVectorSchema.nullable().optional(),
|
|
650
|
+
priority: _zod.z.number().int().default(0),
|
|
651
|
+
content: _zod.z.record(_zod.z.string(), _zod.z.unknown()),
|
|
652
|
+
metadata: _zod.z.record(_zod.z.string(), _zod.z.unknown()).nullable().optional(),
|
|
653
|
+
status: KUIStatusSchema.default("draft"),
|
|
654
|
+
createdAt: _zod.z.string(),
|
|
655
|
+
updatedAt: _zod.z.string()
|
|
656
|
+
});
|
|
657
|
+
var CreateKUIInputSchema = _zod.z.object({
|
|
658
|
+
kudType: _zod.z.string().min(1),
|
|
659
|
+
locale: _zod.z.string().default("en"),
|
|
660
|
+
intentAffinity: IntentVectorSchema,
|
|
661
|
+
intentVelocity: IntentVectorSchema.optional(),
|
|
662
|
+
priority: _zod.z.number().int().default(0),
|
|
663
|
+
content: _zod.z.record(_zod.z.string(), _zod.z.unknown()),
|
|
664
|
+
metadata: _zod.z.record(_zod.z.string(), _zod.z.unknown()).optional()
|
|
665
|
+
});
|
|
666
|
+
var UpdateKUIInputSchema = _zod.z.object({
|
|
667
|
+
locale: _zod.z.string().optional(),
|
|
668
|
+
intentAffinity: IntentVectorSchema.optional(),
|
|
669
|
+
intentVelocity: IntentVectorSchema.nullable().optional(),
|
|
670
|
+
priority: _zod.z.number().int().optional(),
|
|
671
|
+
content: _zod.z.record(_zod.z.string(), _zod.z.unknown()).optional(),
|
|
672
|
+
metadata: _zod.z.record(_zod.z.string(), _zod.z.unknown()).optional(),
|
|
673
|
+
status: KUIStatusSchema.optional()
|
|
674
|
+
});
|
|
675
|
+
var ResolveKUIInputSchema = _zod.z.object({
|
|
676
|
+
kudType: _zod.z.string().min(1),
|
|
677
|
+
intentVector: IntentVectorSchema,
|
|
678
|
+
intentVelocity: IntentVectorSchema.optional(),
|
|
679
|
+
velocityWeight: _zod.z.number().min(0).max(1).default(0.3),
|
|
680
|
+
locale: _zod.z.string().default("en")
|
|
681
|
+
});
|
|
682
|
+
var ListKUIsFilterSchema = _zod.z.object({
|
|
683
|
+
kudType: _zod.z.string().optional(),
|
|
684
|
+
locale: _zod.z.string().optional(),
|
|
685
|
+
status: KUIStatusSchema.optional(),
|
|
686
|
+
intentStage: _zod.z.enum(["awareness", "interest", "consideration", "decision", "evaluation"]).optional()
|
|
687
|
+
});
|
|
688
|
+
|
|
689
|
+
// src/types/layout.ts
|
|
690
|
+
|
|
691
|
+
var PageSlotSchema = _zod.z.object({
|
|
692
|
+
slotId: _zod.z.string(),
|
|
693
|
+
kudId: _zod.z.string(),
|
|
694
|
+
required: _zod.z.boolean().default(true),
|
|
695
|
+
candidateKuiIds: _zod.z.array(_zod.z.string()).optional()
|
|
696
|
+
});
|
|
697
|
+
var PageLayoutSchema = _zod.z.object({
|
|
698
|
+
id: _zod.z.string().uuid(),
|
|
699
|
+
projectId: _zod.z.string(),
|
|
700
|
+
pageId: _zod.z.string(),
|
|
701
|
+
locale: _zod.z.string().default("en"),
|
|
702
|
+
slots: _zod.z.array(PageSlotSchema),
|
|
703
|
+
createdAt: _zod.z.string(),
|
|
704
|
+
updatedAt: _zod.z.string()
|
|
705
|
+
});
|
|
706
|
+
var ResolvedSlotSchema = _zod.z.object({
|
|
707
|
+
slotId: _zod.z.string(),
|
|
708
|
+
kui: KUISchema,
|
|
709
|
+
score: _zod.z.number()
|
|
710
|
+
});
|
|
711
|
+
var ResolvedPageSchema = _zod.z.object({
|
|
712
|
+
pageId: _zod.z.string(),
|
|
713
|
+
slots: _zod.z.array(ResolvedSlotSchema)
|
|
714
|
+
});
|
|
715
|
+
var UpdateLayoutInputSchema = _zod.z.object({
|
|
716
|
+
slots: _zod.z.array(PageSlotSchema)
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
// src/types/config.ts
|
|
720
|
+
|
|
721
|
+
var LexConfigSchema = _zod.z.object({
|
|
722
|
+
$schema: _zod.z.string().optional(),
|
|
723
|
+
version: _zod.z.number().int(),
|
|
724
|
+
name: _zod.z.string(),
|
|
725
|
+
projectId: _zod.z.string(),
|
|
726
|
+
tokens: _zod.z.object({
|
|
727
|
+
source: _zod.z.string(),
|
|
728
|
+
css: _zod.z.string(),
|
|
729
|
+
overrides: _zod.z.record(_zod.z.string(), _zod.z.unknown()).optional()
|
|
730
|
+
}).optional(),
|
|
731
|
+
kuds: _zod.z.object({
|
|
732
|
+
typesFile: _zod.z.string(),
|
|
733
|
+
componentsDir: _zod.z.string(),
|
|
734
|
+
registry: _zod.z.string().default("kuds.registry.json"),
|
|
735
|
+
autoSync: _zod.z.boolean().default(false)
|
|
736
|
+
}).optional(),
|
|
737
|
+
figma: _zod.z.object({
|
|
738
|
+
fileKey: _zod.z.string(),
|
|
739
|
+
variableCollections: _zod.z.array(_zod.z.string()).optional()
|
|
740
|
+
}).optional(),
|
|
741
|
+
api: _zod.z.object({
|
|
742
|
+
baseUrl: _zod.z.string(),
|
|
743
|
+
token: _zod.z.string(),
|
|
744
|
+
routes: _zod.z.string().default("/api/314-lex")
|
|
745
|
+
}).optional(),
|
|
746
|
+
github: _zod.z.object({
|
|
747
|
+
repo: _zod.z.string(),
|
|
748
|
+
branchPrefix: _zod.z.string().optional()
|
|
749
|
+
}).optional()
|
|
750
|
+
});
|
|
751
|
+
var LexClientOptionsSchema = _zod.z.object({
|
|
752
|
+
baseUrl: _zod.z.string().url(),
|
|
753
|
+
token: _zod.z.string().min(1),
|
|
754
|
+
projectId: _zod.z.string().min(1),
|
|
755
|
+
fetch: _zod.z.function().optional()
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
// src/types/tokens.ts
|
|
759
|
+
|
|
760
|
+
var DesignTokenSchema = _zod.z.object({
|
|
761
|
+
id: _zod.z.string().uuid(),
|
|
762
|
+
projectId: _zod.z.string(),
|
|
763
|
+
collection: _zod.z.string(),
|
|
764
|
+
name: _zod.z.string(),
|
|
765
|
+
valueLight: _zod.z.unknown().nullable().optional(),
|
|
766
|
+
valueDark: _zod.z.unknown().nullable().optional(),
|
|
767
|
+
figmaVariableId: _zod.z.string().nullable().optional(),
|
|
768
|
+
updatedAt: _zod.z.string()
|
|
769
|
+
});
|
|
770
|
+
var DTCGTokenSchema = _zod.z.object({
|
|
771
|
+
$value: _zod.z.unknown(),
|
|
772
|
+
$type: _zod.z.string().optional(),
|
|
773
|
+
$description: _zod.z.string().optional()
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
// src/index.ts
|
|
777
|
+
function createLexClient(options) {
|
|
778
|
+
const api = createApiClient(options);
|
|
779
|
+
return {
|
|
780
|
+
kuds: createKudsClient(api, options.projectId),
|
|
781
|
+
kuis: createKuisClient(api, options.projectId),
|
|
782
|
+
layouts: createLayoutsClient(api, options.projectId),
|
|
783
|
+
tokens: createTokensClient(api, options.projectId),
|
|
784
|
+
config: createConfigClient(api, options.projectId)
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
exports.LexApiError = LexApiError; exports.LexValidationError = LexValidationError; exports.LexConfigError = LexConfigError; exports.KUDFieldTypeSchema = KUDFieldTypeSchema; exports.KUDFieldDefSchema = KUDFieldDefSchema; exports.KUDSchema = KUDSchema; exports.CreateKUDInputSchema = CreateKUDInputSchema; exports.UpdateKUDInputSchema = UpdateKUDInputSchema; exports.KudRegistryEntrySchema = KudRegistryEntrySchema; exports.KudRegistrySchema = KudRegistrySchema; exports.IntentVectorSchema = IntentVectorSchema; exports.KUIStatusSchema = KUIStatusSchema; exports.KUISchema = KUISchema; exports.CreateKUIInputSchema = CreateKUIInputSchema; exports.UpdateKUIInputSchema = UpdateKUIInputSchema; exports.ResolveKUIInputSchema = ResolveKUIInputSchema; exports.ListKUIsFilterSchema = ListKUIsFilterSchema; exports.PageSlotSchema = PageSlotSchema; exports.PageLayoutSchema = PageLayoutSchema; exports.ResolvedSlotSchema = ResolvedSlotSchema; exports.ResolvedPageSchema = ResolvedPageSchema; exports.UpdateLayoutInputSchema = UpdateLayoutInputSchema; exports.LexConfigSchema = LexConfigSchema; exports.LexClientOptionsSchema = LexClientOptionsSchema; exports.DesignTokenSchema = DesignTokenSchema; exports.DTCGTokenSchema = DTCGTokenSchema; exports.createLexClient = createLexClient;
|
|
817
|
+
//# sourceMappingURL=chunk-HGZJ53NR.cjs.map
|