catence 0.2.0-beta.14 → 0.2.0-beta.16
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.
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Keep these values synchronized with release/manifest.json; release checks
|
|
4
4
|
* deliberately reject drift before a package can be published.
|
|
5
5
|
*/
|
|
6
|
-
export declare const CATENCE_RUNTIME_VERSION = "0.2.0-beta.
|
|
6
|
+
export declare const CATENCE_RUNTIME_VERSION = "0.2.0-beta.16";
|
|
7
7
|
export declare const CATENCE_PROTOCOL_VERSION = 1;
|
|
8
8
|
export type CatenceRuntimeCapabilities = {
|
|
9
9
|
mcp: true;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Keep these values synchronized with release/manifest.json; release checks
|
|
4
4
|
* deliberately reject drift before a package can be published.
|
|
5
5
|
*/
|
|
6
|
-
export const CATENCE_RUNTIME_VERSION = '0.2.0-beta.
|
|
6
|
+
export const CATENCE_RUNTIME_VERSION = '0.2.0-beta.16';
|
|
7
7
|
export const CATENCE_PROTOCOL_VERSION = 1;
|
|
8
8
|
export function catenceRuntimeHealth() {
|
|
9
9
|
return {
|
|
@@ -528,7 +528,7 @@ export async function reimportNutrition(paths) {
|
|
|
528
528
|
}
|
|
529
529
|
const days = (await database.rows('SELECT count(*) AS count FROM nutrition_days'))[0]?.count ?? 0;
|
|
530
530
|
const items = (await database.rows('SELECT count(*) AS count FROM nutrition_items'))[0]?.count ?? 0;
|
|
531
|
-
return { reimportedEntities: rows.length, nutritionDays: days, nutritionItems: items };
|
|
531
|
+
return { reimportedEntities: rows.length, nutritionDays: Number(days), nutritionItems: Number(items) };
|
|
532
532
|
}
|
|
533
533
|
finally {
|
|
534
534
|
await database.close();
|
|
@@ -63,7 +63,8 @@ function swimSourceLabel(payload) {
|
|
|
63
63
|
function datePart(value) {
|
|
64
64
|
if (!value)
|
|
65
65
|
return null;
|
|
66
|
-
const
|
|
66
|
+
const s = typeof value === 'string' ? value : value.toISOString();
|
|
67
|
+
const match = s.match(/^\d{4}-\d{2}-\d{2}/);
|
|
67
68
|
return match?.[0] ?? null;
|
|
68
69
|
}
|
|
69
70
|
function providerActivityId(provider, remoteId) {
|
|
@@ -143,6 +144,8 @@ function snake(value) {
|
|
|
143
144
|
return value.replace(/([a-z0-9])([A-Z])/g, '$1_$2').replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_+|_+$/g, '').toLowerCase();
|
|
144
145
|
}
|
|
145
146
|
function timestamp(value) {
|
|
147
|
+
if (value instanceof Date)
|
|
148
|
+
return value.toISOString();
|
|
146
149
|
if (typeof value === 'string' && value.length >= 10)
|
|
147
150
|
return value;
|
|
148
151
|
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
@@ -414,7 +417,7 @@ function nested(payload, key) {
|
|
|
414
417
|
return object(payload[key]);
|
|
415
418
|
}
|
|
416
419
|
function metricObservedAt(occurredOn, payload) {
|
|
417
|
-
return firstTimestamp(payload, ['timestamp', 'timestampLocal', 'calendarDate', 'date']) ?? (occurredOn ? `${occurredOn}T00:00:00Z` : null);
|
|
420
|
+
return firstTimestamp(payload, ['timestamp', 'timestampLocal', 'calendarDate', 'date']) ?? (occurredOn ? `${datePart(occurredOn)}T00:00:00Z` : null);
|
|
418
421
|
}
|
|
419
422
|
async function importGarminActivityPerformance(database, remoteId, payload, rawHash) {
|
|
420
423
|
const fields = activityFields('garmin', payload);
|
|
@@ -5,6 +5,28 @@ import { ReadOnlyRepository } from '../../core/query/repository.js';
|
|
|
5
5
|
import { SYNC_STAGES, STALE_RUN_TIMEOUT_MS } from '../../contracts/progress.js';
|
|
6
6
|
import { migrations } from './migrations.js';
|
|
7
7
|
import { json } from './sql.js';
|
|
8
|
+
/**
|
|
9
|
+
* DuckDB's node API throws "Cannot create values of type ANY" when a bound
|
|
10
|
+
* parameter resolves to an untyped value. JS `Date` objects surface as `ANY`
|
|
11
|
+
* (and are not auto-coerced the way strings are), so any date/timestamp
|
|
12
|
+
* parameter read back from the database and re-bound crashes the statement.
|
|
13
|
+
* Serializing dates to ISO strings keeps every parameter concretely typed.
|
|
14
|
+
*/
|
|
15
|
+
function serializeValue(value) {
|
|
16
|
+
if (value instanceof Date)
|
|
17
|
+
return value.toISOString();
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
function serializeBindings(bindings) {
|
|
21
|
+
if (!bindings)
|
|
22
|
+
return bindings;
|
|
23
|
+
if (Array.isArray(bindings))
|
|
24
|
+
return bindings.map(serializeValue);
|
|
25
|
+
const out = {};
|
|
26
|
+
for (const [key, value] of Object.entries(bindings))
|
|
27
|
+
out[key] = serializeValue(value);
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
8
30
|
export class CatenceDatabase {
|
|
9
31
|
instance;
|
|
10
32
|
connection;
|
|
@@ -62,10 +84,10 @@ export class CatenceDatabase {
|
|
|
62
84
|
}
|
|
63
85
|
}
|
|
64
86
|
async run(sql, values) {
|
|
65
|
-
await this.connection.run(sql, values);
|
|
87
|
+
await this.connection.run(sql, serializeBindings(values));
|
|
66
88
|
}
|
|
67
89
|
async rows(sql, values) {
|
|
68
|
-
const result = await this.connection.runAndReadAll(sql, values);
|
|
90
|
+
const result = await this.connection.runAndReadAll(sql, serializeBindings(values));
|
|
69
91
|
return result.getRowObjectsJS();
|
|
70
92
|
}
|
|
71
93
|
async tableNames(query) {
|
package/package.json
CHANGED