@odla-ai/brand 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +72 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +72 -53
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -154,24 +154,6 @@ var BrandReviewStateChangedError = class extends BrandConflictError {
|
|
|
154
154
|
}
|
|
155
155
|
};
|
|
156
156
|
|
|
157
|
-
// src/deps.ts
|
|
158
|
-
async function defaultFetchBytes(url) {
|
|
159
|
-
const res = await fetch(url);
|
|
160
|
-
if (!res.ok) throw new Error(`asset fetch failed: ${res.status} for ${url}`);
|
|
161
|
-
return {
|
|
162
|
-
bytes: new Uint8Array(await res.arrayBuffer()),
|
|
163
|
-
contentType: res.headers.get("content-type") ?? "application/octet-stream"
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
function resolveDeps(deps) {
|
|
167
|
-
return {
|
|
168
|
-
db: deps.db,
|
|
169
|
-
now: deps.now ?? Date.now,
|
|
170
|
-
newId: deps.newId ?? (() => crypto.randomUUID()),
|
|
171
|
-
fetchBytes: deps.fetchBytes ?? defaultFetchBytes
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
|
|
175
157
|
// src/schema.ts
|
|
176
158
|
var a = (type, o = {}) => ({
|
|
177
159
|
type,
|
|
@@ -358,6 +340,70 @@ var BRAND_SCHEMA = {
|
|
|
358
340
|
}
|
|
359
341
|
};
|
|
360
342
|
|
|
343
|
+
// src/read-shape.ts
|
|
344
|
+
var record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
345
|
+
var DATE_FIELDS = /* @__PURE__ */ new Map();
|
|
346
|
+
for (const [ns, entity] of Object.entries(BRAND_SCHEMA.entities))
|
|
347
|
+
DATE_FIELDS.set(
|
|
348
|
+
ns,
|
|
349
|
+
new Set(
|
|
350
|
+
Object.entries(entity.attrs).filter(([, attr]) => attr.type === "date").map(([label]) => label)
|
|
351
|
+
)
|
|
352
|
+
);
|
|
353
|
+
function rowAsWritten(ns, row) {
|
|
354
|
+
const dates = DATE_FIELDS.get(ns);
|
|
355
|
+
if (!dates?.size || !record(row)) return row;
|
|
356
|
+
let changed = false;
|
|
357
|
+
const out = { ...row };
|
|
358
|
+
for (const field of dates) {
|
|
359
|
+
const value = out[field];
|
|
360
|
+
if (typeof value !== "string") continue;
|
|
361
|
+
const parsed = Date.parse(value);
|
|
362
|
+
if (!Number.isSafeInteger(parsed) || parsed < 0) continue;
|
|
363
|
+
out[field] = parsed;
|
|
364
|
+
changed = true;
|
|
365
|
+
}
|
|
366
|
+
return changed ? out : row;
|
|
367
|
+
}
|
|
368
|
+
function receiptAsWritten(row) {
|
|
369
|
+
return rowAsWritten(BRAND_NS.approvalReceipt, row);
|
|
370
|
+
}
|
|
371
|
+
function proposalAsWritten(row) {
|
|
372
|
+
return rowAsWritten(BRAND_NS.proposal, row);
|
|
373
|
+
}
|
|
374
|
+
function resultAsWritten(result) {
|
|
375
|
+
const out = { ...result };
|
|
376
|
+
for (const [ns, rows] of Object.entries(out)) {
|
|
377
|
+
if (Array.isArray(rows)) out[ns] = rows.map((row) => rowAsWritten(ns, row));
|
|
378
|
+
}
|
|
379
|
+
return out;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// src/deps.ts
|
|
383
|
+
async function defaultFetchBytes(url) {
|
|
384
|
+
const res = await fetch(url);
|
|
385
|
+
if (!res.ok) throw new Error(`asset fetch failed: ${res.status} for ${url}`);
|
|
386
|
+
return {
|
|
387
|
+
bytes: new Uint8Array(await res.arrayBuffer()),
|
|
388
|
+
contentType: res.headers.get("content-type") ?? "application/octet-stream"
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function readingAsWritten(db) {
|
|
392
|
+
return {
|
|
393
|
+
query: async (q) => resultAsWritten(await db.query(q)),
|
|
394
|
+
transact: (ops, opts) => db.transact(ops, opts),
|
|
395
|
+
storage: db.storage
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function resolveDeps(deps) {
|
|
399
|
+
return {
|
|
400
|
+
db: readingAsWritten(deps.db),
|
|
401
|
+
now: deps.now ?? Date.now,
|
|
402
|
+
newId: deps.newId ?? (() => crypto.randomUUID()),
|
|
403
|
+
fetchBytes: deps.fetchBytes ?? defaultFetchBytes
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
361
407
|
// src/rules.ts
|
|
362
408
|
var CURRENT_BOOK_MEMBER = "ref('book.memberIds').exists(members, auth.id in members)";
|
|
363
409
|
var BRAND_RULES = {
|
|
@@ -558,38 +604,6 @@ function assertAnalysis(value) {
|
|
|
558
604
|
};
|
|
559
605
|
}
|
|
560
606
|
|
|
561
|
-
// src/read-shape.ts
|
|
562
|
-
var record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
563
|
-
var DATE_FIELDS = /* @__PURE__ */ new Map();
|
|
564
|
-
for (const [ns, entity] of Object.entries(BRAND_SCHEMA.entities))
|
|
565
|
-
DATE_FIELDS.set(
|
|
566
|
-
ns,
|
|
567
|
-
new Set(
|
|
568
|
-
Object.entries(entity.attrs).filter(([, attr]) => attr.type === "date").map(([label]) => label)
|
|
569
|
-
)
|
|
570
|
-
);
|
|
571
|
-
function rowAsWritten(ns, row) {
|
|
572
|
-
const dates = DATE_FIELDS.get(ns);
|
|
573
|
-
if (!dates?.size || !record(row)) return row;
|
|
574
|
-
let changed = false;
|
|
575
|
-
const out = { ...row };
|
|
576
|
-
for (const field of dates) {
|
|
577
|
-
const value = out[field];
|
|
578
|
-
if (typeof value !== "string") continue;
|
|
579
|
-
const parsed = Date.parse(value);
|
|
580
|
-
if (!Number.isSafeInteger(parsed) || parsed < 0) continue;
|
|
581
|
-
out[field] = parsed;
|
|
582
|
-
changed = true;
|
|
583
|
-
}
|
|
584
|
-
return changed ? out : row;
|
|
585
|
-
}
|
|
586
|
-
function receiptAsWritten(row) {
|
|
587
|
-
return rowAsWritten(BRAND_NS.approvalReceipt, row);
|
|
588
|
-
}
|
|
589
|
-
function proposalAsWritten(row) {
|
|
590
|
-
return rowAsWritten(BRAND_NS.proposal, row);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
607
|
// src/review-json.ts
|
|
594
608
|
var record2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
595
609
|
function isBoundedBrandJson(root, limits = {}) {
|
|
@@ -2939,7 +2953,8 @@ async function handleDesignPreview(ctx, req, bookId, assetId) {
|
|
|
2939
2953
|
const asset = await linkedAsset(ctx, book, assetId);
|
|
2940
2954
|
if (asset.kind !== DESIGN_ASSET_KIND) throw new BrandNotFoundError(`design ${assetId}`);
|
|
2941
2955
|
const signed = await ctx.db.storage.sign(asset.path, SIGNED_READ_TTL_SECONDS);
|
|
2942
|
-
const
|
|
2956
|
+
const fetchPrivateAsset = ctx.fetchPrivateAsset;
|
|
2957
|
+
const fetched = await fetchPrivateAsset(signed, {
|
|
2943
2958
|
headers: { accept: "text/html" },
|
|
2944
2959
|
redirect: "manual",
|
|
2945
2960
|
signal: req.signal
|
|
@@ -3824,7 +3839,8 @@ async function handleBrandDiscussionAsset(ctx, req, target) {
|
|
|
3824
3839
|
await ctx.db.storage.sign(before.path, SIGN_TTL_SECONDS)
|
|
3825
3840
|
);
|
|
3826
3841
|
if (!signed) throw new BrandInputError("private asset signing failed");
|
|
3827
|
-
const
|
|
3842
|
+
const fetchPrivateAsset = ctx.fetchPrivateAsset;
|
|
3843
|
+
const response = await fetchPrivateAsset(signed, {
|
|
3828
3844
|
headers: { accept: contentType },
|
|
3829
3845
|
redirect: "manual",
|
|
3830
3846
|
signal: req.signal
|
|
@@ -4061,7 +4077,10 @@ function createBrandRoutes(options) {
|
|
|
4061
4077
|
newId: options.newId ?? (() => crypto.randomUUID()),
|
|
4062
4078
|
maxUploadBytes: options.maxUploadBytes ?? 8 * 1024 * 1024,
|
|
4063
4079
|
discussionBasePath: options.discussionBasePath ?? "/",
|
|
4064
|
-
|
|
4080
|
+
// Bound: this is stored on the context and invoked from route handlers,
|
|
4081
|
+
// where a property call would set the receiver to that context and
|
|
4082
|
+
// Cloudflare's fetch refuses a foreign receiver ("Illegal invocation").
|
|
4083
|
+
fetchPrivateAsset: options.fetchPrivateAsset ?? globalThis.fetch.bind(globalThis),
|
|
4065
4084
|
previewFrameAncestors: options.previewFrameAncestors ?? ["'self'"]
|
|
4066
4085
|
};
|
|
4067
4086
|
return async (req) => {
|