@rebasepro/server-postgres 0.19.2-canary.g98b88fd → 0.19.2-canary.gef769df
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.es.js +10 -47
- package/dist/index.es.js.map +1 -1
- package/dist/services/row-pipeline.d.ts +3 -12
- package/package.json +7 -7
package/dist/index.es.js
CHANGED
|
@@ -2537,49 +2537,12 @@ function coerceDeclaredNumber(value, property) {
|
|
|
2537
2537
|
const parsed = parseFloat(value);
|
|
2538
2538
|
return isNaN(parsed) ? null : parsed;
|
|
2539
2539
|
}
|
|
2540
|
-
/**
|
|
2541
|
-
|
|
2542
|
-
*
|
|
2543
|
-
* The OpenAPI document this server publishes types a `date` property as
|
|
2544
|
-
* `string, format: date-time` — RFC 3339 — and node-postgres hands over the
|
|
2545
|
-
* Postgres literal: `"2026-08-24 01:37:57.647+02"`, with a space where the `T`
|
|
2546
|
-
* belongs and a two-digit offset. V8 parses that by accident; Safari's
|
|
2547
|
-
* `new Date()` does not have to, and the spec never promised it. A column whose
|
|
2548
|
-
* documented type only parses in some browsers is not a contract.
|
|
2549
|
-
*
|
|
2550
|
-
* A date-only column (`mode: "date"`, `format: "date"` in the spec) is already
|
|
2551
|
-
* RFC 3339 as `YYYY-MM-DD` and is left alone — widening it to a timestamp would
|
|
2552
|
-
* invent a time of day and a timezone the column does not have.
|
|
2553
|
-
*/
|
|
2554
|
-
function toRestDate(value) {
|
|
2555
|
-
if (value instanceof Date) return isNaN(value.getTime()) ? null : value.toISOString();
|
|
2556
|
-
if (value && typeof value === "object" && value.__type === "date") return value.value ?? null;
|
|
2557
|
-
if (typeof value !== "string" && typeof value !== "number") return value;
|
|
2558
|
-
if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value)) return value;
|
|
2559
|
-
const date = new Date(value);
|
|
2560
|
-
return isNaN(date.getTime()) ? value : date.toISOString();
|
|
2561
|
-
}
|
|
2562
|
-
/**
|
|
2563
|
-
* One scalar, as REST serves it: declared numbers as numbers, declared dates as
|
|
2564
|
-
* RFC 3339, everything else exactly as the database returned it.
|
|
2565
|
-
*/
|
|
2566
|
-
function toRestScalar(value, property) {
|
|
2567
|
-
if (property?.type === "date") return toRestDate(value);
|
|
2568
|
-
return coerceDeclaredNumber(value, property);
|
|
2569
|
-
}
|
|
2570
|
-
/**
|
|
2571
|
-
* Apply {@link toRestScalar} across a row, leaving undeclared columns alone.
|
|
2572
|
-
*
|
|
2573
|
-
* Exported because the include loader attaches related rows itself, and a
|
|
2574
|
-
* target rendered differently from its parent is the shape bug this whole file
|
|
2575
|
-
* exists to prevent — a date was a string at the top level and a
|
|
2576
|
-
* `{ __type: "date" }` envelope one level down, in the same response.
|
|
2577
|
-
*/
|
|
2578
|
-
function toRestValues(row, collection) {
|
|
2540
|
+
/** Apply {@link coerceDeclaredNumber} across a row, leaving every other column alone. */
|
|
2541
|
+
function coerceDeclaredNumbers(row, collection) {
|
|
2579
2542
|
const properties = collection.properties;
|
|
2580
2543
|
if (!properties) return row;
|
|
2581
2544
|
const out = {};
|
|
2582
|
-
for (const [key, value] of Object.entries(row)) out[key] =
|
|
2545
|
+
for (const [key, value] of Object.entries(row)) out[key] = coerceDeclaredNumber(value, properties[key]);
|
|
2583
2546
|
return out;
|
|
2584
2547
|
}
|
|
2585
2548
|
/** Render one target row in the requested style. */
|
|
@@ -2625,7 +2588,7 @@ function stripUnreadable(row, collection) {
|
|
|
2625
2588
|
return row;
|
|
2626
2589
|
}
|
|
2627
2590
|
function renderTarget(targetRow, targetCollection, style, registry) {
|
|
2628
|
-
if (style === "inline") return stripUnreadable(
|
|
2591
|
+
if (style === "inline") return stripUnreadable(coerceDeclaredNumbers({ ...targetRow }, targetCollection), targetCollection);
|
|
2629
2592
|
const address = relationTargetAddress(targetRow, targetCollection, registry);
|
|
2630
2593
|
const path = targetCollection.slug;
|
|
2631
2594
|
return createRelationRefWithData(address, path, {
|
|
@@ -2675,9 +2638,9 @@ function toFlatRow(row, collection, registry) {
|
|
|
2675
2638
|
*
|
|
2676
2639
|
* Values are the ones the database returned, except where that contradicts the
|
|
2677
2640
|
* declared type: a `number` property is served as a number (see
|
|
2678
|
-
* {@link coerceDeclaredNumber})
|
|
2679
|
-
*
|
|
2680
|
-
*
|
|
2641
|
+
* {@link coerceDeclaredNumber}). Dates stay as the database returned them —
|
|
2642
|
+
* JSON has its own opinions about dates that the admin's view-model does not
|
|
2643
|
+
* share.
|
|
2681
2644
|
*
|
|
2682
2645
|
* Keyed by the row rather than by the relation list — a REST fetch only loads
|
|
2683
2646
|
* the relations `include` asked for, so the row is the authority on which are
|
|
@@ -2690,7 +2653,7 @@ function toRestRow(row, collection, registry) {
|
|
|
2690
2653
|
const relation = findRelation(resolvedRelations, key);
|
|
2691
2654
|
if (relation && Array.isArray(value)) flat[key] = value.map((item) => renderTarget(isJunctionRelation(relation) ? unwrapJunctionRow(item) : item, relation.target(), "inline", registry));
|
|
2692
2655
|
else if (relation && typeof value === "object" && value !== null) flat[key] = renderTarget(value, relation.target(), "inline", registry);
|
|
2693
|
-
else flat[key] =
|
|
2656
|
+
else flat[key] = coerceDeclaredNumber(value, collection.properties?.[key]);
|
|
2694
2657
|
}
|
|
2695
2658
|
return stripUnreadable(flat, collection);
|
|
2696
2659
|
}
|
|
@@ -3946,7 +3909,7 @@ var FetchService = class FetchService {
|
|
|
3946
3909
|
row[key] = null;
|
|
3947
3910
|
continue;
|
|
3948
3911
|
}
|
|
3949
|
-
const [shaped] = this.shapeRelatedRows([
|
|
3912
|
+
const [shaped] = this.shapeRelatedRows([{ ...related.values }], node, targetCollection);
|
|
3950
3913
|
row[key] = shaped;
|
|
3951
3914
|
loaded.push(shaped);
|
|
3952
3915
|
}
|
|
@@ -3954,7 +3917,7 @@ var FetchService = class FetchService {
|
|
|
3954
3917
|
const results = await this.relationService.batchFetchRelatedEntitiesMany(collectionPath, rowIds, key, relation, narrow);
|
|
3955
3918
|
for (const row of addressable) {
|
|
3956
3919
|
const related = results.get(String(addressOf(row))) ?? [];
|
|
3957
|
-
const shaped = this.shapeRelatedRows(related.map((e) =>
|
|
3920
|
+
const shaped = this.shapeRelatedRows(related.map((e) => ({ ...e.values })), node, targetCollection);
|
|
3958
3921
|
row[key] = shaped;
|
|
3959
3922
|
loaded.push(...shaped);
|
|
3960
3923
|
}
|