@seedprotocol/sdk 0.6.7 → 0.6.8
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/{BasePathResolver-qV0apdVY.js → BasePathResolver-B6CKqoKw.js} +16 -5
- package/dist/BasePathResolver-B6CKqoKw.js.map +1 -0
- package/dist/{ClientManager-Y5EWQuJj.js → ClientManager-ChcmUL47.js} +619 -264
- package/dist/ClientManager-ChcmUL47.js.map +1 -0
- package/dist/{ModelProperty-DuB5nk6A.js → ModelProperty-D79uV42p.js} +33 -30
- package/dist/ModelProperty-D79uV42p.js.map +1 -0
- package/dist/{Schema-BYM-GNdE.js → Schema-a8uO-hIZ.js} +43 -43
- package/dist/Schema-a8uO-hIZ.js.map +1 -0
- package/dist/{SchemaValidationService-Dr6nmwPm.js → SchemaValidationService-Y49vqast.js} +13 -12
- package/dist/SchemaValidationService-Y49vqast.js.map +1 -0
- package/dist/{backfillMetadataPropertyIds-BzbAB-C5.js → backfillMetadataPropertyIds-CBsf7LnU.js} +5 -3
- package/dist/{backfillMetadataPropertyIds-BzbAB-C5.js.map → backfillMetadataPropertyIds-CBsf7LnU.js.map} +1 -1
- package/dist/cjs/{ModelProperty-CDTOx5zi.js → ModelProperty-D9FGaGuE.js} +21 -17
- package/dist/cjs/ModelProperty-D9FGaGuE.js.map +1 -0
- package/dist/cjs/{Schema-XXcwj3hV.js → Schema-BiJIPLEL.js} +25 -24
- package/dist/cjs/Schema-BiJIPLEL.js.map +1 -0
- package/dist/cjs/{SchemaValidationService-Z7OhtGn5.js → SchemaValidationService-DtYs_CNY.js} +5 -3
- package/dist/cjs/SchemaValidationService-DtYs_CNY.js.map +1 -0
- package/dist/cjs/{backfillMetadataPropertyIds-Bt4fzfIV.js → backfillMetadataPropertyIds-2XaN3b9S.js} +3 -2
- package/dist/cjs/{backfillMetadataPropertyIds-Bt4fzfIV.js.map → backfillMetadataPropertyIds-2XaN3b9S.js.map} +1 -1
- package/dist/cjs/{eas-DdI-4vwl.js → eas-CMNppmGE.js} +4 -3
- package/dist/cjs/{eas-DdI-4vwl.js.map → eas-CMNppmGE.js.map} +1 -1
- package/dist/cjs/{getItem-B_2GeTQf.js → getItem-B6jEINjW.js} +3 -2
- package/dist/cjs/{getItem-B_2GeTQf.js.map → getItem-B6jEINjW.js.map} +1 -1
- package/dist/cjs/{getPublishPayload-Jmgi1RUj.js → getPublishPayload-D5DhLGvN.js} +64 -59
- package/dist/cjs/getPublishPayload-D5DhLGvN.js.map +1 -0
- package/dist/cjs/{getPublishUploads-DNULcrN5.js → getPublishUploads-DMhCCKYF.js} +17 -10
- package/dist/cjs/getPublishUploads-DMhCCKYF.js.map +1 -0
- package/dist/cjs/{getSegmentedItemProperties-DK82kjri.js → getSegmentedItemProperties-CU8rtBAo.js} +3 -51
- package/dist/cjs/getSegmentedItemProperties-CU8rtBAo.js.map +1 -0
- package/dist/cjs/{index-DM1WR83P.js → index-CSNtEnbF.js} +879 -467
- package/dist/cjs/index-CSNtEnbF.js.map +1 -0
- package/dist/cjs/{index-tpO1Nj4v.js → index-DPp9rdRL.js} +6 -3
- package/dist/cjs/index-DPp9rdRL.js.map +1 -0
- package/dist/cjs/{property-DmvgA8FD.js → property-DlKiAWt4.js} +7 -4
- package/dist/cjs/{property-DmvgA8FD.js.map → property-DlKiAWt4.js.map} +1 -1
- package/dist/cjs/{syncDbWithEas-3hOoPdu1.js → syncDbWithEas-C6n34o_Q.js} +11 -6
- package/dist/cjs/syncDbWithEas-C6n34o_Q.js.map +1 -0
- package/dist/{configurePlatform-CCYQruij.js → configurePlatform-CE0Vew17.js} +5 -5
- package/dist/{configurePlatform-CCYQruij.js.map → configurePlatform-CE0Vew17.js.map} +1 -1
- package/dist/db/drizzle/0014_add_error_code_to_publish_processes.sql +1 -0
- package/dist/db/drizzle/meta/0014_snapshot.json +1269 -0
- package/dist/db/drizzle/meta/_journal.json +7 -0
- package/dist/{db-CceyWksv.js → db-WbrzEf7c.js} +254 -35
- package/dist/db-WbrzEf7c.js.map +1 -0
- package/dist/{eas-CH8iFIST.js → eas-CfYCu4IX.js} +6 -6
- package/dist/{eas-CH8iFIST.js.map → eas-CfYCu4IX.js.map} +1 -1
- package/dist/{getItem-C7Mtfz6O.js → getItem-Br-bGNFO.js} +6 -6
- package/dist/{getItem-C7Mtfz6O.js.map → getItem-Br-bGNFO.js.map} +1 -1
- package/dist/{getPublishPayload-2gnnDdMh.js → getPublishPayload-BIrTVUxb.js} +66 -62
- package/dist/getPublishPayload-BIrTVUxb.js.map +1 -0
- package/dist/{getPublishUploads-AKISt3JA.js → getPublishUploads-C6cDeZdz.js} +19 -13
- package/dist/getPublishUploads-C6cDeZdz.js.map +1 -0
- package/dist/{getSegmentedItemProperties-eIjvhCP_.js → getSegmentedItemProperties-BmKE71vU.js} +5 -5
- package/dist/{getSegmentedItemProperties-eIjvhCP_.js.map → getSegmentedItemProperties-BmKE71vU.js.map} +1 -1
- package/dist/{constants-DSqHBPNe.js → index-280bL-n4.js} +32 -257
- package/dist/index-280bL-n4.js.map +1 -0
- package/dist/{index-CHi212ST.js → index-ClSv5pTA.js} +13 -13
- package/dist/index-ClSv5pTA.js.map +1 -0
- package/dist/{index-CsmiM0RI.js → index-Djd3667v.js} +2 -2
- package/dist/index-Djd3667v.js.map +1 -0
- package/dist/{index-BFpbtEsg.js → index-HRHkbVQd.js} +24 -24
- package/dist/{index-BFpbtEsg.js.map → index-HRHkbVQd.js.map} +1 -1
- package/dist/{index.node-CbWB4MDz.js → index.node-DBtQkEfz.js} +8 -6
- package/dist/index.node-DBtQkEfz.js.map +1 -0
- package/dist/main.cjs +6 -1
- package/dist/main.cjs.map +1 -1
- package/dist/main.js +36 -38
- package/dist/main.js.map +1 -1
- package/dist/node.js +15 -14
- package/dist/node.js.map +1 -1
- package/dist/platform.browser.js +108 -46
- package/dist/platform.browser.js.map +1 -1
- package/dist/platform.node.js +4 -3
- package/dist/platform.node.js.map +1 -1
- package/dist/{property-CWKcZ5YZ.js → property-CQjuZ4JW.js} +14 -13
- package/dist/property-CQjuZ4JW.js.map +1 -0
- package/dist/seedSchema/PublishProcessSchema.ts +1 -0
- package/dist/src/Item/Item.d.ts +6 -0
- package/dist/src/Item/Item.d.ts.map +1 -1
- package/dist/src/Item/service/actors/loadOrCreateItem.d.ts.map +1 -1
- package/dist/src/ItemProperty/ItemProperty.d.ts +10 -1
- package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/resolveRelatedValue.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveRelation.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/propertyMachine.d.ts.map +1 -1
- package/dist/src/ModelProperty/ModelProperty.d.ts.map +1 -1
- package/dist/src/Schema/service/actors/loadOrCreateSchema.d.ts.map +1 -1
- package/dist/src/Schema/service/actors/writeModelsToDb.d.ts.map +1 -1
- package/dist/src/Schema/service/addModelsMachine.d.ts.map +1 -1
- package/dist/src/Schema/service/validation/SchemaValidationService.d.ts.map +1 -1
- package/dist/src/browser/db/drizzleFiles.d.ts +3 -2
- package/dist/src/browser/db/drizzleFiles.d.ts.map +1 -1
- package/dist/src/browser/helpers/ArweaveClient.d.ts.map +1 -1
- package/dist/src/browser/helpers/EasClient.d.ts +2 -1
- package/dist/src/browser/helpers/EasClient.d.ts.map +1 -1
- package/dist/src/browser/helpers/FileManager.d.ts +1 -1
- package/dist/src/browser/helpers/FileManager.d.ts.map +1 -1
- package/dist/src/browser/workers/FileDownloader.d.ts +1 -1
- package/dist/src/browser/workers/FileDownloader.d.ts.map +1 -1
- package/dist/src/browser/workers/filesDownload.d.ts.map +1 -1
- package/dist/src/client/actors/platformClassesInit.d.ts.map +1 -1
- package/dist/src/client/actors/saveConfig.d.ts.map +1 -1
- package/dist/src/client/constants.d.ts +4 -0
- package/dist/src/client/constants.d.ts.map +1 -1
- package/dist/src/client/nodeEndpointDefaults.d.ts +8 -0
- package/dist/src/client/nodeEndpointDefaults.d.ts.map +1 -0
- package/dist/src/db/read/getPublishPayload.d.ts.map +1 -1
- package/dist/src/db/read/getPublishUploads.d.ts.map +1 -1
- package/dist/src/db/read/getRelatedItemsForPublish.d.ts.map +1 -1
- package/dist/src/db/write/createMetadata.d.ts.map +1 -1
- package/dist/src/events/files/download.d.ts.map +1 -1
- package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
- package/dist/src/helpers/ArweaveClient/index.d.ts.map +1 -1
- package/dist/src/helpers/FileManager/BaseFileManager.d.ts +2 -2
- package/dist/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
- package/dist/src/helpers/FileManager/IFileManager.d.ts +4 -0
- package/dist/src/helpers/FileManager/IFileManager.d.ts.map +1 -1
- package/dist/src/helpers/constants.d.ts +8 -0
- package/dist/src/helpers/constants.d.ts.map +1 -1
- package/dist/src/helpers/db.d.ts +6 -0
- package/dist/src/helpers/db.d.ts.map +1 -1
- package/dist/src/helpers/gateway/gatewayState.d.ts +1 -1
- package/dist/src/helpers/gateway/gatewayState.d.ts.map +1 -1
- package/dist/src/helpers/localDbChain.d.ts +22 -0
- package/dist/src/helpers/localDbChain.d.ts.map +1 -0
- package/dist/src/helpers/metadataPropertyNames.d.ts +9 -0
- package/dist/src/helpers/metadataPropertyNames.d.ts.map +1 -1
- package/dist/src/helpers/property/index.d.ts +12 -0
- package/dist/src/helpers/property/index.d.ts.map +1 -1
- package/dist/src/helpers/readHtmlBodyForStorageSeed.d.ts.map +1 -1
- package/dist/src/helpers/relationSeedRef.d.ts +8 -0
- package/dist/src/helpers/relationSeedRef.d.ts.map +1 -1
- package/dist/src/index.d.ts +9 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/node/easLodashHook.d.ts +2 -0
- package/dist/src/node/easLodashHook.d.ts.map +1 -0
- package/dist/src/node/easLodashRegister.d.ts +2 -0
- package/dist/src/node/easLodashRegister.d.ts.map +1 -0
- package/dist/src/node/helpers/FileManager.d.ts +2 -1
- package/dist/src/node/helpers/FileManager.d.ts.map +1 -1
- package/dist/src/node/index.d.ts +2 -1
- package/dist/src/node/index.d.ts.map +1 -1
- package/dist/src/seedSchema/PublishProcessSchema.d.ts +19 -0
- package/dist/src/seedSchema/PublishProcessSchema.d.ts.map +1 -1
- package/dist/src/types/fileManager.d.ts +4 -0
- package/dist/src/types/fileManager.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +15 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/{syncDbWithEas-5kZneTEL.js → syncDbWithEas-CuARXfyN.js} +16 -12
- package/dist/syncDbWithEas-CuARXfyN.js.map +1 -0
- package/dist/{updateSeedRevokedAt-CgfOBtqJ.js → updateSeedRevokedAt-CBcLfHWs.js} +2 -2
- package/dist/{updateSeedRevokedAt-CgfOBtqJ.js.map → updateSeedRevokedAt-CBcLfHWs.js.map} +1 -1
- package/package.json +11 -7
- package/src/node/easLodashHook.js +22 -0
- package/src/node/easLodashRegister.js +13 -0
- package/dist/BasePathResolver-qV0apdVY.js.map +0 -1
- package/dist/ClientManager-Y5EWQuJj.js.map +0 -1
- package/dist/ModelProperty-DuB5nk6A.js.map +0 -1
- package/dist/Schema-BYM-GNdE.js.map +0 -1
- package/dist/SchemaValidationService-Dr6nmwPm.js.map +0 -1
- package/dist/cjs/ModelProperty-CDTOx5zi.js.map +0 -1
- package/dist/cjs/Schema-XXcwj3hV.js.map +0 -1
- package/dist/cjs/SchemaValidationService-Z7OhtGn5.js.map +0 -1
- package/dist/cjs/getPublishPayload-Jmgi1RUj.js.map +0 -1
- package/dist/cjs/getPublishUploads-DNULcrN5.js.map +0 -1
- package/dist/cjs/getSegmentedItemProperties-DK82kjri.js.map +0 -1
- package/dist/cjs/index-DM1WR83P.js.map +0 -1
- package/dist/cjs/index-tpO1Nj4v.js.map +0 -1
- package/dist/cjs/syncDbWithEas-3hOoPdu1.js.map +0 -1
- package/dist/constants-DSqHBPNe.js.map +0 -1
- package/dist/db-CceyWksv.js.map +0 -1
- package/dist/getPublishPayload-2gnnDdMh.js.map +0 -1
- package/dist/getPublishUploads-AKISt3JA.js.map +0 -1
- package/dist/index-CHi212ST.js.map +0 -1
- package/dist/index-CsmiM0RI.js.map +0 -1
- package/dist/index.node-CbWB4MDz.js.map +0 -1
- package/dist/property-CWKcZ5YZ.js.map +0 -1
- package/dist/seedSchema/AppStateSchema.d.ts +0 -82
- package/dist/seedSchema/AppStateSchema.d.ts.map +0 -1
- package/dist/seedSchema/ConfigSchema.d.ts +0 -101
- package/dist/seedSchema/ConfigSchema.d.ts.map +0 -1
- package/dist/seedSchema/MetadataSchema.d.ts +0 -422
- package/dist/seedSchema/MetadataSchema.d.ts.map +0 -1
- package/dist/seedSchema/ModelSchema.d.ts +0 -243
- package/dist/seedSchema/ModelSchema.d.ts.map +0 -1
- package/dist/seedSchema/ModelSchemaSchema.d.ts +0 -61
- package/dist/seedSchema/ModelSchemaSchema.d.ts.map +0 -1
- package/dist/seedSchema/ModelUidSchema.d.ts +0 -64
- package/dist/seedSchema/ModelUidSchema.d.ts.map +0 -1
- package/dist/seedSchema/PropertyUidSchema.d.ts +0 -64
- package/dist/seedSchema/PropertyUidSchema.d.ts.map +0 -1
- package/dist/seedSchema/SchemaSchema.d.ts +0 -169
- package/dist/seedSchema/SchemaSchema.d.ts.map +0 -1
- package/dist/seedSchema/SeedSchema.d.ts +0 -192
- package/dist/seedSchema/SeedSchema.d.ts.map +0 -1
- package/dist/seedSchema/VersionSchema.d.ts +0 -194
- package/dist/seedSchema/VersionSchema.d.ts.map +0 -1
- package/dist/seedSchema/index.d.ts +0 -14
- package/dist/seedSchema/index.d.ts.map +0 -1
- package/dist/syncDbWithEas-5kZneTEL.js.map +0 -1
|
@@ -21,6 +21,7 @@ var utils = require('@noble/hashes/utils');
|
|
|
21
21
|
var fsAsync = require('fs/promises');
|
|
22
22
|
var fs = require('fs');
|
|
23
23
|
var path = require('path');
|
|
24
|
+
var url = require('url');
|
|
24
25
|
var node_url = require('node:url');
|
|
25
26
|
var client = require('@libsql/client');
|
|
26
27
|
var libsql = require('drizzle-orm/libsql');
|
|
@@ -204,17 +205,19 @@ class BaseFileManager {
|
|
|
204
205
|
static getContentUrlFromPath(path) {
|
|
205
206
|
return BaseFileManager.requireImpl().getContentUrlFromPath(path);
|
|
206
207
|
}
|
|
207
|
-
static downloadAllFiles({ transactionIds, arweaveHost, excludedTransactions, }) {
|
|
208
|
+
static downloadAllFiles({ transactionIds, arweaveHost, arweaveBaseUrls, excludedTransactions, }) {
|
|
208
209
|
return BaseFileManager.requireImpl().downloadAllFiles({
|
|
209
210
|
transactionIds,
|
|
210
211
|
arweaveHost,
|
|
212
|
+
arweaveBaseUrls,
|
|
211
213
|
excludedTransactions,
|
|
212
214
|
});
|
|
213
215
|
}
|
|
214
|
-
static downloadFileByTransactionId({ transactionId, arweaveHost, excludedTransactions, }) {
|
|
216
|
+
static downloadFileByTransactionId({ transactionId, arweaveHost, arweaveBaseUrls, excludedTransactions, }) {
|
|
215
217
|
return BaseFileManager.requireImpl().downloadAllFiles({
|
|
216
218
|
transactionIds: [transactionId],
|
|
217
219
|
arweaveHost,
|
|
220
|
+
arweaveBaseUrls,
|
|
218
221
|
excludedTransactions,
|
|
219
222
|
});
|
|
220
223
|
}
|
|
@@ -429,6 +432,50 @@ function normalizeDataType(value) {
|
|
|
429
432
|
const lower = value.toLowerCase().trim();
|
|
430
433
|
return DATA_TYPE_LOWER_MAP[lower] ?? value.charAt(0).toUpperCase() + value.slice(1).toLowerCase();
|
|
431
434
|
}
|
|
435
|
+
/**
|
|
436
|
+
* Case-insensitive dataType check. Use instead of `dataType === 'List'` so schemas
|
|
437
|
+
* (or existing DB rows) with lowercase types like "list" still match.
|
|
438
|
+
*/
|
|
439
|
+
function isDataType(value, expected) {
|
|
440
|
+
if (!value)
|
|
441
|
+
return false;
|
|
442
|
+
return normalizeDataType(value) === expected;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Normalize a property definition to the internal shape ItemProperty reads (`dataType`,
|
|
446
|
+
* `refValueType`, `ref`, `storageType`, ...). Accepts schema-file shape (`type`, `model`,
|
|
447
|
+
* `items`, `storage`) and any casing. Mirrors the conversion in imports/json createModelFromJson
|
|
448
|
+
* for the fallback paths that read schema-file properties directly.
|
|
449
|
+
*/
|
|
450
|
+
function normalizePropertyRecordSchema(def) {
|
|
451
|
+
if (!def || typeof def !== 'object')
|
|
452
|
+
return def;
|
|
453
|
+
const src = def;
|
|
454
|
+
const out = { ...src };
|
|
455
|
+
const rawType = src.dataType ?? src.type;
|
|
456
|
+
if (typeof rawType === 'string' && rawType)
|
|
457
|
+
out.dataType = normalizeDataType(rawType);
|
|
458
|
+
const ref = src.ref ?? src.refModelName ?? src.items?.model ?? src.model;
|
|
459
|
+
if (ref && !out.ref)
|
|
460
|
+
out.ref = ref;
|
|
461
|
+
if (ref && !out.refModelName)
|
|
462
|
+
out.refModelName = ref;
|
|
463
|
+
const rawRefValueType = src.refValueType ?? src.items?.type;
|
|
464
|
+
if (typeof rawRefValueType === 'string' && rawRefValueType) {
|
|
465
|
+
out.refValueType = normalizeDataType(rawRefValueType);
|
|
466
|
+
}
|
|
467
|
+
else if (out.dataType === exports.ModelPropertyDataTypes.List && ref) {
|
|
468
|
+
out.refValueType = exports.ModelPropertyDataTypes.Relation;
|
|
469
|
+
}
|
|
470
|
+
if (src.storage && typeof src.storage === 'object' && !out.storageType) {
|
|
471
|
+
out.storageType = src.storage.type === 'ItemStorage' ? 'ItemStorage' : 'PropertyStorage';
|
|
472
|
+
if (src.storage.path !== undefined && out.localStorageDir === undefined)
|
|
473
|
+
out.localStorageDir = src.storage.path;
|
|
474
|
+
if (src.storage.extension !== undefined && out.filenameSuffix === undefined)
|
|
475
|
+
out.filenameSuffix = src.storage.extension;
|
|
476
|
+
}
|
|
477
|
+
return out;
|
|
478
|
+
}
|
|
432
479
|
const TPropertyDataType = typebox.Type.Union([
|
|
433
480
|
typebox.Type.Literal(exports.ModelPropertyDataTypes.Text),
|
|
434
481
|
typebox.Type.Literal(exports.ModelPropertyDataTypes.Number),
|
|
@@ -538,20 +585,34 @@ const Boolean$1 = () => PropertyConstructor(Property.Boolean());
|
|
|
538
585
|
const Date$1 = () => PropertyConstructor(Property.Date());
|
|
539
586
|
const Html = (opts) => PropertyConstructor(htmlPropertyFactory(opts));
|
|
540
587
|
|
|
541
|
-
/**
|
|
542
|
-
|
|
543
|
-
* internal storage/EAS name: `authorIdentityIds` (singular + ref + Ids).
|
|
544
|
-
*/
|
|
545
|
-
function listRelationStoragePropertyName(propertySchemas, schemaPropertyKey) {
|
|
546
|
-
const propDef = propertySchemas[schemaPropertyKey];
|
|
588
|
+
/** Ref model name when propDef is a List of Relation, else undefined. */
|
|
589
|
+
function listRelationRef(propDef) {
|
|
547
590
|
if (!propDef)
|
|
548
591
|
return undefined;
|
|
549
592
|
if (normalizeDataType(propDef.dataType) !== 'List')
|
|
550
593
|
return undefined;
|
|
551
|
-
|
|
552
|
-
|
|
594
|
+
return propDef.ref || propDef.refModelName || undefined;
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Storage/EAS name for a List-of-relation property (`authorIdentityIds`), given either its
|
|
598
|
+
* schema key (`authors`) or its storage name. A name already in storage form is returned as-is,
|
|
599
|
+
* so this is safe on ItemProperties built before their schema was known.
|
|
600
|
+
* Returns undefined when propDef is not a List of Relation.
|
|
601
|
+
*/
|
|
602
|
+
function listRelationEasPropertyName(propertyName, propDef) {
|
|
603
|
+
const ref = listRelationRef(propDef);
|
|
604
|
+
if (!ref || !propertyName)
|
|
553
605
|
return undefined;
|
|
554
|
-
|
|
606
|
+
if (propertyName.endsWith(`${ref}Ids`))
|
|
607
|
+
return propertyName;
|
|
608
|
+
return `${pluralize(propertyName, 1)}${ref}Ids`;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* For a schema property key like `authors` (List of Relation to Identity), returns the
|
|
612
|
+
* internal storage/EAS name: `authorIdentityIds` (singular + ref + Ids).
|
|
613
|
+
*/
|
|
614
|
+
function listRelationStoragePropertyName(propertySchemas, schemaPropertyKey) {
|
|
615
|
+
return listRelationEasPropertyName(schemaPropertyKey, propertySchemas[schemaPropertyKey]);
|
|
555
616
|
}
|
|
556
617
|
/**
|
|
557
618
|
* Reverse of listRelationStoragePropertyName: maps DB/EAS name `authorIdentityIds` to schema key `authors`.
|
|
@@ -668,6 +729,73 @@ function resolveMetadataRecord(records, preferredPropertyName, dataType, refValu
|
|
|
668
729
|
return (records.find((r) => r.propertyName === preferredPropertyName) ?? records[0]);
|
|
669
730
|
}
|
|
670
731
|
|
|
732
|
+
/** Same rules as getCorrectId in helpers/index (avoid barrel circular import). */
|
|
733
|
+
function parseLocalIdOrUid(localIdOrUid) {
|
|
734
|
+
const id = { localId: undefined, uid: undefined };
|
|
735
|
+
if (!localIdOrUid)
|
|
736
|
+
return id;
|
|
737
|
+
if (localIdOrUid.length === 10) {
|
|
738
|
+
id.localId = localIdOrUid;
|
|
739
|
+
}
|
|
740
|
+
if (localIdOrUid.startsWith('0x') && localIdOrUid.length === 66) {
|
|
741
|
+
id.uid = localIdOrUid;
|
|
742
|
+
}
|
|
743
|
+
return id;
|
|
744
|
+
}
|
|
745
|
+
/** Relation/image refs may be string ids or `{ seedLocalId?, seedUid? }`. */
|
|
746
|
+
function normalizeRelationPropertyValue(value) {
|
|
747
|
+
if (value == null)
|
|
748
|
+
return undefined;
|
|
749
|
+
if (typeof value === 'string') {
|
|
750
|
+
const t = value.trim();
|
|
751
|
+
return t !== '' ? t : undefined;
|
|
752
|
+
}
|
|
753
|
+
if (typeof value === 'object' && value !== null) {
|
|
754
|
+
const o = value;
|
|
755
|
+
if (typeof o.seedLocalId === 'string' && o.seedLocalId.trim() !== '') {
|
|
756
|
+
return o.seedLocalId.trim();
|
|
757
|
+
}
|
|
758
|
+
if (typeof o.seedUid === 'string' && o.seedUid.trim() !== '') {
|
|
759
|
+
return o.seedUid.trim();
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
return undefined;
|
|
763
|
+
}
|
|
764
|
+
/** getCorrectId only accepts 10-char local ids and 0x66 uids; local seed refs can be up to 21 chars. */
|
|
765
|
+
const LOCAL_SEED_REF = /^[a-zA-Z0-9_-]{10,21}$/;
|
|
766
|
+
/** Resolve seed ids from a single string (context propertyValue or DB row). */
|
|
767
|
+
function resolveSeedIdsFromRefString(s) {
|
|
768
|
+
const fromCorrect = parseLocalIdOrUid(s);
|
|
769
|
+
if (fromCorrect.localId || fromCorrect.uid) {
|
|
770
|
+
return { seedLocalId: fromCorrect.localId, seedUid: fromCorrect.uid };
|
|
771
|
+
}
|
|
772
|
+
if (LOCAL_SEED_REF.test(s) && !s.startsWith('0x')) {
|
|
773
|
+
return { seedLocalId: s };
|
|
774
|
+
}
|
|
775
|
+
return {};
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* True when a relation ref is an attested seed uid (0x…) rather than a local id. A uid only exists once
|
|
779
|
+
* the seed is on EAS, so publish can attest the uid as-is when no local copy exists (e.g. a server
|
|
780
|
+
* publishing on someone's behalf that only holds the uids it was given). Callers must not walk into it.
|
|
781
|
+
*/
|
|
782
|
+
function isPublishedSeedRef(value) {
|
|
783
|
+
const ref = normalizeRelationPropertyValue(value);
|
|
784
|
+
if (!ref)
|
|
785
|
+
return false;
|
|
786
|
+
const { seedLocalId, seedUid } = resolveSeedIdsFromRefString(ref);
|
|
787
|
+
return !!seedUid && !seedLocalId;
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* Storage seed local id (nanoid) or 0x uid. Stricter than resolveSeedIdsFromRefString, which accepts
|
|
791
|
+
* any 10-char string (so a 10-char html snippet like "<p>raw</p>" would pass as a local id).
|
|
792
|
+
*/
|
|
793
|
+
const STORAGE_SEED_REF = /^(?:[A-Za-z0-9_-]{10,21}|0x[0-9a-fA-F]{64})$/;
|
|
794
|
+
/** True when a File/Image/Html value is already a storage seed reference rather than raw content. */
|
|
795
|
+
function isStorageSeedRef(value) {
|
|
796
|
+
return typeof value === 'string' && STORAGE_SEED_REF.test(value.trim());
|
|
797
|
+
}
|
|
798
|
+
|
|
671
799
|
const seeds = sqliteCore.sqliteTable('seeds', {
|
|
672
800
|
localId: sqliteCore.text('local_id').unique(),
|
|
673
801
|
uid: sqliteCore.text('uid'),
|
|
@@ -805,6 +933,7 @@ const publishProcesses = sqliteCore.sqliteTable('publish_processes', {
|
|
|
805
933
|
errorMessage: sqliteCore.text('error_message'),
|
|
806
934
|
errorStep: sqliteCore.text('error_step'),
|
|
807
935
|
errorDetails: sqliteCore.text('error_details'),
|
|
936
|
+
errorCode: sqliteCore.text('error_code'), // e.g. ManagedAccountPublishError.code
|
|
808
937
|
persistedSnapshot: sqliteCore.text('persisted_snapshot').notNull(),
|
|
809
938
|
seedId: sqliteCore.text('seed_id'),
|
|
810
939
|
existingSeedUid: sqliteCore.text('existing_seed_uid'),
|
|
@@ -1072,7 +1201,52 @@ function normalizeAddressConfig(addresses) {
|
|
|
1072
1201
|
};
|
|
1073
1202
|
}
|
|
1074
1203
|
|
|
1075
|
-
|
|
1204
|
+
/**
|
|
1205
|
+
* Convert Model.properties array to object format (for backward compatibility)
|
|
1206
|
+
* This replaces the old model.schema getter
|
|
1207
|
+
*/
|
|
1208
|
+
function modelPropertiesToObject(properties) {
|
|
1209
|
+
const schemaObj = {};
|
|
1210
|
+
for (const property of properties) {
|
|
1211
|
+
const propContext = property._getSnapshotContext();
|
|
1212
|
+
if (propContext.name) {
|
|
1213
|
+
schemaObj[propContext.name] = {
|
|
1214
|
+
dataType: propContext.dataType,
|
|
1215
|
+
ref: propContext.refModelName || propContext.ref,
|
|
1216
|
+
refValueType: propContext.refValueType,
|
|
1217
|
+
storageType: propContext.storageType,
|
|
1218
|
+
localStorageDir: propContext.localStorageDir,
|
|
1219
|
+
filenameSuffix: propContext.filenameSuffix,
|
|
1220
|
+
required: propContext.required,
|
|
1221
|
+
};
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
return schemaObj;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
var model = /*#__PURE__*/Object.freeze({
|
|
1228
|
+
__proto__: null,
|
|
1229
|
+
modelPropertiesToObject: modelPropertiesToObject
|
|
1230
|
+
});
|
|
1231
|
+
|
|
1232
|
+
const logger$y = debug('seedSdk:helpers:db');
|
|
1233
|
+
/**
|
|
1234
|
+
* Resolve property_id (integer properties.id) from a property's schemaFileId (the string `id` in
|
|
1235
|
+
* schema files and propertyRecordSchema). Scoped to the model since schemaFileIds are per schema file.
|
|
1236
|
+
* @returns properties.id or null if not found
|
|
1237
|
+
*/
|
|
1238
|
+
async function getPropertyIdForSchemaFileId(modelNameOrType, schemaFileId) {
|
|
1239
|
+
const db = BaseDb.getAppDb();
|
|
1240
|
+
if (!db || !modelNameOrType || !schemaFileId)
|
|
1241
|
+
return null;
|
|
1242
|
+
const rows = await db
|
|
1243
|
+
.select({ id: properties.id })
|
|
1244
|
+
.from(properties)
|
|
1245
|
+
.innerJoin(models$1, drizzleOrm.eq(properties.modelId, models$1.id))
|
|
1246
|
+
.where(drizzleOrm.and(drizzleOrm.eq(models$1.name, lodashEs.upperFirst(lodashEs.camelCase(modelNameOrType))), drizzleOrm.eq(properties.schemaFileId, schemaFileId)))
|
|
1247
|
+
.limit(1);
|
|
1248
|
+
return rows[0]?.id ?? null;
|
|
1249
|
+
}
|
|
1076
1250
|
/**
|
|
1077
1251
|
* Resolve property_id from model name/type and property name.
|
|
1078
1252
|
* Handles property name variants (e.g. htmlId -> html, avatarImageIds -> avatarImages).
|
|
@@ -1120,28 +1294,19 @@ async function getPropertyIdForModelAndName(modelNameOrType, propertyName) {
|
|
|
1120
1294
|
async function migrateMetadataForPropertyRename(modelName, oldPropertyName, newPropertyName, propertySchemaFileId) {
|
|
1121
1295
|
const db = BaseDb.getAppDb();
|
|
1122
1296
|
if (!db) {
|
|
1123
|
-
logger$
|
|
1297
|
+
logger$y('[migrateMetadataForPropertyRename] Database not available, skipping');
|
|
1124
1298
|
return 0;
|
|
1125
1299
|
}
|
|
1126
|
-
const normalizedModelName = lodashEs.upperFirst(lodashEs.camelCase(modelName));
|
|
1127
1300
|
// Find the property row by schemaFileId (preferred) or by name
|
|
1128
1301
|
let propertyId = null;
|
|
1129
1302
|
if (propertySchemaFileId) {
|
|
1130
|
-
|
|
1131
|
-
.select({ id: properties.id })
|
|
1132
|
-
.from(properties)
|
|
1133
|
-
.innerJoin(models$1, drizzleOrm.eq(properties.modelId, models$1.id))
|
|
1134
|
-
.where(drizzleOrm.and(drizzleOrm.eq(models$1.name, normalizedModelName), drizzleOrm.eq(properties.schemaFileId, propertySchemaFileId)))
|
|
1135
|
-
.limit(1);
|
|
1136
|
-
if (rows.length > 0 && rows[0].id != null) {
|
|
1137
|
-
propertyId = rows[0].id;
|
|
1138
|
-
}
|
|
1303
|
+
propertyId = await getPropertyIdForSchemaFileId(modelName, propertySchemaFileId);
|
|
1139
1304
|
}
|
|
1140
1305
|
if (propertyId == null) {
|
|
1141
1306
|
propertyId = await getPropertyIdForModelAndName(modelName, oldPropertyName);
|
|
1142
1307
|
}
|
|
1143
1308
|
if (propertyId == null) {
|
|
1144
|
-
logger$
|
|
1309
|
+
logger$y(`[migrateMetadataForPropertyRename] Property not found: ${modelName}.${oldPropertyName}, skipping`);
|
|
1145
1310
|
return 0;
|
|
1146
1311
|
}
|
|
1147
1312
|
// Primary path: update metadata by propertyId
|
|
@@ -1170,11 +1335,11 @@ async function migrateMetadataForPropertyRename(modelName, oldPropertyName, newP
|
|
|
1170
1335
|
.where(drizzleOrm.and(drizzleOrm.eq(metadata$1.propertyName, oldPropertyName), drizzleOrm.eq(metadata$1.modelType, modelType), drizzleOrm.isNull(metadata$1.propertyId)));
|
|
1171
1336
|
}
|
|
1172
1337
|
if (updatedByFallback > 0) {
|
|
1173
|
-
logger$
|
|
1338
|
+
logger$y(`[migrateMetadataForPropertyRename] Fallback updated ${updatedByFallback} rows (propertyId was null)`);
|
|
1174
1339
|
}
|
|
1175
1340
|
const total = updatedByPropertyId + updatedByFallback;
|
|
1176
1341
|
if (total > 0) {
|
|
1177
|
-
logger$
|
|
1342
|
+
logger$y(`[migrateMetadataForPropertyRename] Migrated ${total} metadata rows for ${modelName}.${oldPropertyName} -> ${newPropertyName}`);
|
|
1178
1343
|
}
|
|
1179
1344
|
return total;
|
|
1180
1345
|
}
|
|
@@ -1274,7 +1439,7 @@ const findOrCreateModelRecord = async (db, modelName, modelFileId) => {
|
|
|
1274
1439
|
.set({ schemaFileId: modelFileId, isEdited: false })
|
|
1275
1440
|
.where(drizzleOrm.eq(models$1.id, chosen.id));
|
|
1276
1441
|
chosen = { ...chosen, schemaFileId: modelFileId, isEdited: false };
|
|
1277
|
-
logger$
|
|
1442
|
+
logger$y(`Adopted existing model "${modelName}" (id: ${chosen.id}) with schemaFileId "${modelFileId}"`);
|
|
1278
1443
|
}
|
|
1279
1444
|
}
|
|
1280
1445
|
return chosen;
|
|
@@ -1521,7 +1686,7 @@ const addSchemaToDb = async (schema, schemaFileId, schemaData, isDraft, isEdited
|
|
|
1521
1686
|
.limit(1);
|
|
1522
1687
|
if (draftSchemas.length > 0) {
|
|
1523
1688
|
// Found a draft - we'll update it to non-draft below
|
|
1524
|
-
logger$
|
|
1689
|
+
logger$y(`Found draft schema "${schema.name}" with schemaFileId "${draftSchemas[0].schemaFileId}", will update to non-draft with schemaFileId "${schemaFileId}"`);
|
|
1525
1690
|
existingSchemas = draftSchemas;
|
|
1526
1691
|
}
|
|
1527
1692
|
}
|
|
@@ -1541,11 +1706,11 @@ const addSchemaToDb = async (schema, schemaFileId, schemaData, isDraft, isEdited
|
|
|
1541
1706
|
!existingSchemas[0].schemaFileId ||
|
|
1542
1707
|
(isDraft === false && existingSchemas[0].isDraft === true);
|
|
1543
1708
|
if (shouldUpdate) {
|
|
1544
|
-
logger$
|
|
1709
|
+
logger$y(`Updating schemaFileId from "${existingSchemas[0].schemaFileId}" to "${schemaFileId}" for schema "${schema.name}"`);
|
|
1545
1710
|
updates.schemaFileId = schemaFileId;
|
|
1546
1711
|
}
|
|
1547
1712
|
else {
|
|
1548
|
-
logger$
|
|
1713
|
+
logger$y(`Preserving existing schemaFileId "${existingSchemas[0].schemaFileId}" for non-draft schema "${schema.name}" (new schemaFileId "${schemaFileId}" would overwrite it)`);
|
|
1549
1714
|
}
|
|
1550
1715
|
}
|
|
1551
1716
|
// Always update name if it's different (handles name changes)
|
|
@@ -1572,16 +1737,16 @@ const addSchemaToDb = async (schema, schemaFileId, schemaData, isDraft, isEdited
|
|
|
1572
1737
|
updates.updatedAt = schema.updatedAt;
|
|
1573
1738
|
}
|
|
1574
1739
|
if (Object.keys(updates).length > 0) {
|
|
1575
|
-
logger$
|
|
1740
|
+
logger$y(`Applying updates to schema "${schema.name}" (id: ${existingSchemas[0].id}):`, Object.keys(updates));
|
|
1576
1741
|
await db
|
|
1577
1742
|
.update(schemas)
|
|
1578
1743
|
.set(updates)
|
|
1579
1744
|
.where(drizzleOrm.eq(schemas.id, existingSchemas[0].id));
|
|
1580
1745
|
const updated = { ...existingSchemas[0], ...updates };
|
|
1581
|
-
logger$
|
|
1746
|
+
logger$y(`Schema "${schema.name}" updated. New schemaFileId: "${updated.schemaFileId}", isDraft: ${updated.isDraft}`);
|
|
1582
1747
|
return updated;
|
|
1583
1748
|
}
|
|
1584
|
-
logger$
|
|
1749
|
+
logger$y(`No updates needed for schema "${schema.name}" (id: ${existingSchemas[0].id})`);
|
|
1585
1750
|
return existingSchemas[0];
|
|
1586
1751
|
}
|
|
1587
1752
|
const newSchema = await db.insert(schemas).values({
|
|
@@ -1762,7 +1927,7 @@ async function checkIfPropertyIsEdited(modelName, propertyName, schemaFileValue)
|
|
|
1762
1927
|
// Compare database value with schema file value
|
|
1763
1928
|
// If they differ, the property has been edited
|
|
1764
1929
|
if (dbProperty.dataType !== schemaFileValue.dataType) {
|
|
1765
|
-
logger$
|
|
1930
|
+
logger$y(`Property ${modelName}:${propertyName} has been edited (dataType differs: DB=${dbProperty.dataType}, Schema=${schemaFileValue.dataType})`);
|
|
1766
1931
|
return true;
|
|
1767
1932
|
}
|
|
1768
1933
|
// Check refModelId if it's a relation
|
|
@@ -1775,19 +1940,19 @@ async function checkIfPropertyIsEdited(modelName, propertyName, schemaFileValue)
|
|
|
1775
1940
|
if (refModelRecords.length > 0) {
|
|
1776
1941
|
const expectedRefModelId = refModelRecords[0].id;
|
|
1777
1942
|
if (dbProperty.refModelId !== expectedRefModelId) {
|
|
1778
|
-
logger$
|
|
1943
|
+
logger$y(`Property ${modelName}:${propertyName} has been edited (refModelId differs)`);
|
|
1779
1944
|
return true;
|
|
1780
1945
|
}
|
|
1781
1946
|
}
|
|
1782
1947
|
}
|
|
1783
1948
|
else if (dbProperty.refModelId !== null) {
|
|
1784
1949
|
// Schema file has no ref, but DB has one
|
|
1785
|
-
logger$
|
|
1950
|
+
logger$y(`Property ${modelName}:${propertyName} has been edited (refModelId differs)`);
|
|
1786
1951
|
return true;
|
|
1787
1952
|
}
|
|
1788
1953
|
// Check refValueType
|
|
1789
1954
|
if (dbProperty.refValueType !== (schemaFileValue.refValueType || null)) {
|
|
1790
|
-
logger$
|
|
1955
|
+
logger$y(`Property ${modelName}:${propertyName} has been edited (refValueType differs)`);
|
|
1791
1956
|
return true;
|
|
1792
1957
|
}
|
|
1793
1958
|
// Check required (for Relation/Image properties)
|
|
@@ -1795,7 +1960,7 @@ async function checkIfPropertyIsEdited(modelName, propertyName, schemaFileValue)
|
|
|
1795
1960
|
const schemaRequired = !!schemaFileValue.required;
|
|
1796
1961
|
const dbRequired = dbProperty.required === true;
|
|
1797
1962
|
if (dbRequired !== schemaRequired) {
|
|
1798
|
-
logger$
|
|
1963
|
+
logger$y(`Property ${modelName}:${propertyName} has been edited (required differs: DB=${dbRequired}, Schema=${schemaRequired})`);
|
|
1799
1964
|
return true;
|
|
1800
1965
|
}
|
|
1801
1966
|
}
|
|
@@ -1807,7 +1972,7 @@ async function checkIfPropertyIsEdited(modelName, propertyName, schemaFileValue)
|
|
|
1807
1972
|
}
|
|
1808
1973
|
catch (error) {
|
|
1809
1974
|
// If we can't check, assume it's not edited to be safe
|
|
1810
|
-
logger$
|
|
1975
|
+
logger$y('Error checking if property is edited:', error);
|
|
1811
1976
|
return false;
|
|
1812
1977
|
}
|
|
1813
1978
|
}
|
|
@@ -1832,11 +1997,11 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
1832
1997
|
// SchemaType includes id, so check if it's set
|
|
1833
1998
|
if (schema.id !== null && schema.id !== undefined) {
|
|
1834
1999
|
schemaRecord = schema;
|
|
1835
|
-
logger$
|
|
2000
|
+
logger$y(`Using existing schema record with id: ${schemaRecord.id}`);
|
|
1836
2001
|
}
|
|
1837
2002
|
else {
|
|
1838
2003
|
schemaRecord = await addSchemaToDb(schema, schemaFileData?.schemaFileId);
|
|
1839
|
-
logger$
|
|
2004
|
+
logger$y(`Created/found schema record with id: ${schemaRecord.id}`);
|
|
1840
2005
|
}
|
|
1841
2006
|
}
|
|
1842
2007
|
// Handle model renames first if provided
|
|
@@ -1862,7 +2027,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
1862
2027
|
.where(drizzleOrm.eq(models$1.schemaFileId, modelFileId))
|
|
1863
2028
|
.limit(1);
|
|
1864
2029
|
if (existingWithFileId.length > 0 && existingWithFileId[0].id !== modelRecord.id) {
|
|
1865
|
-
logger$
|
|
2030
|
+
logger$y(`WARNING: Model "${modelName}" (id: ${modelRecord.id}) conflicts with existing model "${existingWithFileId[0].name}" (id: ${existingWithFileId[0].id}) both trying to use schemaFileId "${modelFileId}"`);
|
|
1866
2031
|
modelRecord = existingWithFileId[0];
|
|
1867
2032
|
}
|
|
1868
2033
|
else if (!modelRecord.schemaFileId) {
|
|
@@ -1920,7 +2085,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
1920
2085
|
if (!propertyFileId) {
|
|
1921
2086
|
const { generateId } = await Promise.resolve().then(function () { return generateId$1; });
|
|
1922
2087
|
propertyFileId = generateId();
|
|
1923
|
-
logger$
|
|
2088
|
+
logger$y(`Generated propertyFileId "${propertyFileId}" for property "${modelName}:${propertyName}" (not found in propertyFileIds map)`);
|
|
1924
2089
|
}
|
|
1925
2090
|
// First, try to find by schemaFileId (preferred for change tracking)
|
|
1926
2091
|
let existingProperty;
|
|
@@ -1935,7 +2100,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
1935
2100
|
const propertyData = {
|
|
1936
2101
|
name: propertyName,
|
|
1937
2102
|
modelId: modelRecord.id,
|
|
1938
|
-
dataType: propertyValues.dataType,
|
|
2103
|
+
dataType: normalizeDataType(propertyValues.dataType),
|
|
1939
2104
|
schemaFileId: propertyFileId || null,
|
|
1940
2105
|
required: propertyValues.required ?? false,
|
|
1941
2106
|
};
|
|
@@ -1961,7 +2126,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
1961
2126
|
propertyData.refModelId = null;
|
|
1962
2127
|
}
|
|
1963
2128
|
if (propertyValues.refValueType) {
|
|
1964
|
-
propertyData.refValueType = propertyValues.refValueType;
|
|
2129
|
+
propertyData.refValueType = normalizeDataType(propertyValues.refValueType);
|
|
1965
2130
|
}
|
|
1966
2131
|
else {
|
|
1967
2132
|
// If refValueType is not set, ensure it's null
|
|
@@ -1985,7 +2150,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
1985
2150
|
if (potentialMatches.length > 0) {
|
|
1986
2151
|
const matchedProperty = potentialMatches[0];
|
|
1987
2152
|
existingProperty = matchedProperty;
|
|
1988
|
-
logger$
|
|
2153
|
+
logger$y(`Found renamed property: ${modelName}:${matchedProperty.name} -> ${propertyName} (matched by characteristics)`);
|
|
1989
2154
|
}
|
|
1990
2155
|
}
|
|
1991
2156
|
if (existingProperty) {
|
|
@@ -2005,7 +2170,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
2005
2170
|
});
|
|
2006
2171
|
if (isPropertyEdited) {
|
|
2007
2172
|
// Property has been locally edited - skip update to preserve local changes
|
|
2008
|
-
logger$
|
|
2173
|
+
logger$y(`Skipping update for property ${modelName}:${existingProperty.name} -> ${propertyName} - it has been locally edited and will be preserved`);
|
|
2009
2174
|
continue;
|
|
2010
2175
|
}
|
|
2011
2176
|
// Property exists (possibly with different name) - update it with new values from schema file
|
|
@@ -2053,18 +2218,18 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
2053
2218
|
if (existingByFileId.length > 0) {
|
|
2054
2219
|
const found = existingByFileId[0];
|
|
2055
2220
|
matchedDbPropertyIds.add(found.id);
|
|
2056
|
-
logger$
|
|
2221
|
+
logger$y(`Property ${modelName}:${propertyName} already exists by schemaFileId "${propertyFileId}" (id: ${found.id}), skipping insert`);
|
|
2057
2222
|
continue;
|
|
2058
2223
|
}
|
|
2059
2224
|
}
|
|
2060
|
-
logger$
|
|
2225
|
+
logger$y(`Creating new property ${modelName}:${propertyName} with schemaFileId: ${propertyData.schemaFileId}`);
|
|
2061
2226
|
try {
|
|
2062
2227
|
await db.insert(properties).values(propertyDataWithIsEdited);
|
|
2063
2228
|
}
|
|
2064
2229
|
catch (insertError) {
|
|
2065
2230
|
// Treat UNIQUE constraint as success - property already exists (e.g. from concurrent addModelsToDb call)
|
|
2066
2231
|
if (isSqliteUniqueConstraintError(insertError)) {
|
|
2067
|
-
logger$
|
|
2232
|
+
logger$y(`Property ${modelName}:${propertyName} already exists (UNIQUE constraint), treating as success`);
|
|
2068
2233
|
}
|
|
2069
2234
|
else {
|
|
2070
2235
|
throw insertError;
|
|
@@ -2075,14 +2240,14 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
2075
2240
|
}
|
|
2076
2241
|
catch (error) {
|
|
2077
2242
|
const errorMessage = error?.message || String(error);
|
|
2078
|
-
logger$
|
|
2243
|
+
logger$y(`Error processing model "${modelName}": ${errorMessage}`);
|
|
2079
2244
|
modelProcessingErrors.push({ modelName, error: errorMessage });
|
|
2080
2245
|
// Continue processing other models even if one fails
|
|
2081
2246
|
}
|
|
2082
2247
|
}
|
|
2083
2248
|
if (modelProcessingErrors.length > 0) {
|
|
2084
2249
|
console.warn(`[addModelsToDb] Errors occurred while processing ${modelProcessingErrors.length} model(s):`, modelProcessingErrors.map(e => `${e.modelName}: ${e.error}`).join('; '));
|
|
2085
|
-
logger$
|
|
2250
|
+
logger$y(`Errors processing models: ${modelProcessingErrors.map(e => e.modelName).join(', ')}`);
|
|
2086
2251
|
}
|
|
2087
2252
|
// If schema was provided, create modelSchema join records to connect models to the schema
|
|
2088
2253
|
if (schemaRecord && schemaRecord.id) {
|
|
@@ -2090,7 +2255,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
2090
2255
|
.filter(([, r]) => r.id)
|
|
2091
2256
|
.map(([name, r]) => ({ modelName: name, modelId: r.id }));
|
|
2092
2257
|
if (modelIds.length === 0) {
|
|
2093
|
-
logger$
|
|
2258
|
+
logger$y('No model IDs to link, skipping schema linking');
|
|
2094
2259
|
}
|
|
2095
2260
|
else {
|
|
2096
2261
|
// Single batch query: get all existing joins for this schema
|
|
@@ -2106,13 +2271,13 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
2106
2271
|
modelId,
|
|
2107
2272
|
schemaId: schemaRecord.id,
|
|
2108
2273
|
});
|
|
2109
|
-
logger$
|
|
2274
|
+
logger$y(`Created join table entry for model ${modelName} (id: ${modelId}) to schema (id: ${schemaRecord.id})`);
|
|
2110
2275
|
}
|
|
2111
2276
|
}
|
|
2112
2277
|
}
|
|
2113
2278
|
}
|
|
2114
2279
|
else if (schemaRecord && !schemaRecord.id) {
|
|
2115
|
-
logger$
|
|
2280
|
+
logger$y(`Warning: schemaRecord provided but has no id, cannot create join table entries`);
|
|
2116
2281
|
}
|
|
2117
2282
|
};
|
|
2118
2283
|
/**
|
|
@@ -2125,7 +2290,7 @@ const addModelsToDb$1 = async (models, schema, modelRenames, schemaFileData) =>
|
|
|
2125
2290
|
const loadModelsFromDbForSchema = async (schemaId) => {
|
|
2126
2291
|
const db = BaseDb.getAppDb();
|
|
2127
2292
|
if (!db) {
|
|
2128
|
-
logger$
|
|
2293
|
+
logger$y('Database not found, cannot load models from DB');
|
|
2129
2294
|
return {};
|
|
2130
2295
|
}
|
|
2131
2296
|
try {
|
|
@@ -2156,7 +2321,7 @@ const loadModelsFromDbForSchema = async (schemaId) => {
|
|
|
2156
2321
|
// Note: This is a simplified reconstruction - full property schemas
|
|
2157
2322
|
// (like Relation details, List configs, etc.) should come from schemaData
|
|
2158
2323
|
const propertyData = {
|
|
2159
|
-
dataType: prop.dataType,
|
|
2324
|
+
dataType: normalizeDataType(prop.dataType ?? undefined),
|
|
2160
2325
|
};
|
|
2161
2326
|
if (prop.schemaFileId) {
|
|
2162
2327
|
propertyData.schemaFileId = prop.schemaFileId;
|
|
@@ -2174,7 +2339,7 @@ const loadModelsFromDbForSchema = async (schemaId) => {
|
|
|
2174
2339
|
}
|
|
2175
2340
|
}
|
|
2176
2341
|
if (prop.refValueType) {
|
|
2177
|
-
propertyData.refValueType = prop.refValueType;
|
|
2342
|
+
propertyData.refValueType = normalizeDataType(prop.refValueType ?? undefined);
|
|
2178
2343
|
}
|
|
2179
2344
|
modelProperties[prop.name] = propertyData;
|
|
2180
2345
|
}
|
|
@@ -2188,11 +2353,11 @@ const loadModelsFromDbForSchema = async (schemaId) => {
|
|
|
2188
2353
|
// or reconstructed from schemaData if available
|
|
2189
2354
|
};
|
|
2190
2355
|
}
|
|
2191
|
-
logger$
|
|
2356
|
+
logger$y(`Loaded ${Object.keys(models).length} models from database for schema ${schemaId}`);
|
|
2192
2357
|
return models;
|
|
2193
2358
|
}
|
|
2194
2359
|
catch (error) {
|
|
2195
|
-
logger$
|
|
2360
|
+
logger$y(`Error loading models from database for schema ${schemaId}:`, error);
|
|
2196
2361
|
return {};
|
|
2197
2362
|
}
|
|
2198
2363
|
};
|
|
@@ -2313,40 +2478,40 @@ const savePropertyToDb = async (property) => {
|
|
|
2313
2478
|
// Find existing property - try multiple strategies to handle name changes
|
|
2314
2479
|
// 1. First try by schemaFileId (most reliable - doesn't change when name changes)
|
|
2315
2480
|
let existingProperties = [];
|
|
2316
|
-
logger$
|
|
2481
|
+
logger$y(`[savePropertyToDb] Looking for property ${property.modelName}:${property.name} (schemaFileId: ${schemaFileId}, originalName: ${property._originalValues?.name})`);
|
|
2317
2482
|
if (schemaFileId) {
|
|
2318
2483
|
existingProperties = await db
|
|
2319
2484
|
.select()
|
|
2320
2485
|
.from(properties)
|
|
2321
2486
|
.where(drizzleOrm.and(drizzleOrm.eq(properties.schemaFileId, schemaFileId), drizzleOrm.eq(properties.modelId, modelRecord.id)))
|
|
2322
2487
|
.limit(1);
|
|
2323
|
-
logger$
|
|
2488
|
+
logger$y(`[savePropertyToDb] Found ${existingProperties.length} properties by schemaFileId`);
|
|
2324
2489
|
}
|
|
2325
2490
|
// 2. If not found by schemaFileId, try by original name (if name was changed)
|
|
2326
2491
|
if (existingProperties.length === 0 && property._originalValues?.name && property._originalValues.name !== property.name) {
|
|
2327
|
-
logger$
|
|
2492
|
+
logger$y(`[savePropertyToDb] Trying to find by original name: ${property._originalValues.name}`);
|
|
2328
2493
|
existingProperties = await db
|
|
2329
2494
|
.select()
|
|
2330
2495
|
.from(properties)
|
|
2331
2496
|
.where(drizzleOrm.and(drizzleOrm.eq(properties.name, property._originalValues.name), drizzleOrm.eq(properties.modelId, modelRecord.id)))
|
|
2332
2497
|
.limit(1);
|
|
2333
|
-
logger$
|
|
2498
|
+
logger$y(`[savePropertyToDb] Found ${existingProperties.length} properties by original name`);
|
|
2334
2499
|
}
|
|
2335
2500
|
// 3. Fallback: try by current name
|
|
2336
2501
|
if (existingProperties.length === 0) {
|
|
2337
|
-
logger$
|
|
2502
|
+
logger$y(`[savePropertyToDb] Trying to find by current name: ${property.name}`);
|
|
2338
2503
|
existingProperties = await db
|
|
2339
2504
|
.select()
|
|
2340
2505
|
.from(properties)
|
|
2341
2506
|
.where(drizzleOrm.and(drizzleOrm.eq(properties.name, property.name), drizzleOrm.eq(properties.modelId, modelRecord.id)))
|
|
2342
2507
|
.limit(1);
|
|
2343
|
-
logger$
|
|
2508
|
+
logger$y(`[savePropertyToDb] Found ${existingProperties.length} properties by current name`);
|
|
2344
2509
|
}
|
|
2345
2510
|
// Prepare property data
|
|
2346
2511
|
const propertyData = {
|
|
2347
2512
|
name: property.name,
|
|
2348
2513
|
modelId: modelRecord.id,
|
|
2349
|
-
dataType: property.dataType
|
|
2514
|
+
dataType: normalizeDataType(property.dataType),
|
|
2350
2515
|
};
|
|
2351
2516
|
// Preserve schemaFileId if we have it
|
|
2352
2517
|
if (schemaFileId) {
|
|
@@ -2367,7 +2532,7 @@ const savePropertyToDb = async (property) => {
|
|
|
2367
2532
|
propertyData.refModelId = null;
|
|
2368
2533
|
}
|
|
2369
2534
|
if (property.refValueType) {
|
|
2370
|
-
propertyData.refValueType = property.refValueType;
|
|
2535
|
+
propertyData.refValueType = normalizeDataType(property.refValueType);
|
|
2371
2536
|
}
|
|
2372
2537
|
else {
|
|
2373
2538
|
// If refValueType is not set, ensure it's null
|
|
@@ -2385,7 +2550,7 @@ const savePropertyToDb = async (property) => {
|
|
|
2385
2550
|
isEdited: true, // Mark as edited when saving changes
|
|
2386
2551
|
})
|
|
2387
2552
|
.where(drizzleOrm.eq(properties.id, existingProperty.id));
|
|
2388
|
-
logger$
|
|
2553
|
+
logger$y(`Updated property ${property.modelName}:${property._originalValues?.name || 'unknown'} -> ${property.name} in database`);
|
|
2389
2554
|
}
|
|
2390
2555
|
else {
|
|
2391
2556
|
// Property doesn't exist, create it
|
|
@@ -2395,12 +2560,12 @@ const savePropertyToDb = async (property) => {
|
|
|
2395
2560
|
...propertyData,
|
|
2396
2561
|
isEdited: true, // Runtime-created properties are edited
|
|
2397
2562
|
});
|
|
2398
|
-
logger$
|
|
2563
|
+
logger$y(`Created property ${property.modelName}:${property.name} in database`);
|
|
2399
2564
|
}
|
|
2400
2565
|
catch (insertError) {
|
|
2401
2566
|
// Treat UNIQUE constraint as success - property already exists (e.g. from concurrent addModelsToDb or race)
|
|
2402
2567
|
if (isSqliteUniqueConstraintError(insertError)) {
|
|
2403
|
-
logger$
|
|
2568
|
+
logger$y(`Property ${property.modelName}:${property.name} already exists (UNIQUE constraint), treating as success`);
|
|
2404
2569
|
}
|
|
2405
2570
|
else {
|
|
2406
2571
|
throw insertError;
|
|
@@ -2517,7 +2682,7 @@ async function writeModelToDb(modelFileId, data) {
|
|
|
2517
2682
|
if (doubleCheck.length > 0) {
|
|
2518
2683
|
// Another process created it, use existing
|
|
2519
2684
|
modelId = doubleCheck[0].id;
|
|
2520
|
-
logger$
|
|
2685
|
+
logger$y(`Model with schemaFileId "${modelFileId}" was created by another process, using existing record (id: ${modelId})`);
|
|
2521
2686
|
}
|
|
2522
2687
|
else {
|
|
2523
2688
|
try {
|
|
@@ -2531,7 +2696,7 @@ async function writeModelToDb(modelFileId, data) {
|
|
|
2531
2696
|
catch (error) {
|
|
2532
2697
|
// Handle unique constraint violation
|
|
2533
2698
|
if (isSqliteUniqueConstraintError(error)) {
|
|
2534
|
-
logger$
|
|
2699
|
+
logger$y(`Unique constraint violation for schemaFileId "${modelFileId}", attempting to find existing model`);
|
|
2535
2700
|
const existing = await db
|
|
2536
2701
|
.select()
|
|
2537
2702
|
.from(models$1)
|
|
@@ -2539,7 +2704,7 @@ async function writeModelToDb(modelFileId, data) {
|
|
|
2539
2704
|
.limit(1);
|
|
2540
2705
|
if (existing.length > 0) {
|
|
2541
2706
|
modelId = existing[0].id;
|
|
2542
|
-
logger$
|
|
2707
|
+
logger$y(`Found existing model with schemaFileId "${modelFileId}" (id: ${modelId}) after constraint violation`);
|
|
2543
2708
|
}
|
|
2544
2709
|
else {
|
|
2545
2710
|
throw error;
|
|
@@ -2609,7 +2774,7 @@ async function writeModelToDb(modelFileId, data) {
|
|
|
2609
2774
|
if (schemaCheck.length === 0) {
|
|
2610
2775
|
throw new Error(`Schema with id ${data.schemaId} does not exist in database. Cannot create join record.`);
|
|
2611
2776
|
}
|
|
2612
|
-
logger$
|
|
2777
|
+
logger$y(`Creating join record: modelId=${modelId}, schemaId=${data.schemaId} (both verified to exist)`);
|
|
2613
2778
|
await db.insert(modelSchemas).values({
|
|
2614
2779
|
modelId,
|
|
2615
2780
|
schemaId: data.schemaId,
|
|
@@ -2627,13 +2792,13 @@ async function writeModelToDb(modelFileId, data) {
|
|
|
2627
2792
|
}
|
|
2628
2793
|
catch (_) { }
|
|
2629
2794
|
}
|
|
2630
|
-
logger$
|
|
2795
|
+
logger$y(`Successfully created join record for model ${data.modelName} (id: ${modelId}) to schema (id: ${data.schemaId})`);
|
|
2631
2796
|
}
|
|
2632
2797
|
catch (error) {
|
|
2633
2798
|
if (error?.code === 'SQLITE_CONSTRAINT_FOREIGNKEY') {
|
|
2634
|
-
logger$
|
|
2635
|
-
logger$
|
|
2636
|
-
logger$
|
|
2799
|
+
logger$y(`FOREIGN KEY constraint failed when creating join record for model "${data.modelName}"`);
|
|
2800
|
+
logger$y(`modelId: ${modelId}, schemaId: ${data.schemaId}`);
|
|
2801
|
+
logger$y(`Error details:`, error);
|
|
2637
2802
|
// Re-throw with more context
|
|
2638
2803
|
throw new Error(`FOREIGN KEY constraint failed when creating join record for model "${data.modelName}" (modelId: ${modelId}, schemaId: ${data.schemaId}). ${error.message}`);
|
|
2639
2804
|
}
|
|
@@ -2653,7 +2818,7 @@ async function writeModelToDb(modelFileId, data) {
|
|
|
2653
2818
|
if (existingProps.length > 0 && existingProps[0].schemaFileId) {
|
|
2654
2819
|
// Use existing property's schemaFileId
|
|
2655
2820
|
propertyFileId = existingProps[0].schemaFileId;
|
|
2656
|
-
logger$
|
|
2821
|
+
logger$y(`Using existing propertyFileId "${propertyFileId}" for property "${data.modelName}:${propName}"`);
|
|
2657
2822
|
}
|
|
2658
2823
|
else if (propData.id) {
|
|
2659
2824
|
// Use provided ID
|
|
@@ -2664,7 +2829,7 @@ async function writeModelToDb(modelFileId, data) {
|
|
|
2664
2829
|
// IDs should be generated in the import process before calling writeModelToDb
|
|
2665
2830
|
const { generateId } = await Promise.resolve().then(function () { return generateId$1; });
|
|
2666
2831
|
propertyFileId = generateId();
|
|
2667
|
-
logger$
|
|
2832
|
+
logger$y(`Generated propertyFileId "${propertyFileId}" for property "${data.modelName}:${propName}"`);
|
|
2668
2833
|
}
|
|
2669
2834
|
await writePropertyToDb(propertyFileId, {
|
|
2670
2835
|
modelId,
|
|
@@ -2673,7 +2838,7 @@ async function writeModelToDb(modelFileId, data) {
|
|
|
2673
2838
|
});
|
|
2674
2839
|
}
|
|
2675
2840
|
}
|
|
2676
|
-
logger$
|
|
2841
|
+
logger$y(`Wrote model ${data.modelName} (${modelFileId}) to database`);
|
|
2677
2842
|
}
|
|
2678
2843
|
/**
|
|
2679
2844
|
* Write property to database
|
|
@@ -2703,7 +2868,7 @@ async function writePropertyToDb(propertyFileId, data, isEdited = false) {
|
|
|
2703
2868
|
const propertyData = {
|
|
2704
2869
|
name: data.name,
|
|
2705
2870
|
modelId: data.modelId,
|
|
2706
|
-
dataType: data.dataType
|
|
2871
|
+
dataType: normalizeDataType(data.dataType),
|
|
2707
2872
|
schemaFileId: propertyFileId,
|
|
2708
2873
|
isEdited: isEdited, // Persist isEdited flag
|
|
2709
2874
|
};
|
|
@@ -2724,7 +2889,7 @@ async function writePropertyToDb(propertyFileId, data, isEdited = false) {
|
|
|
2724
2889
|
propertyData.refModelId = null;
|
|
2725
2890
|
}
|
|
2726
2891
|
if (data.refValueType) {
|
|
2727
|
-
propertyData.refValueType = data.refValueType;
|
|
2892
|
+
propertyData.refValueType = normalizeDataType(data.refValueType);
|
|
2728
2893
|
}
|
|
2729
2894
|
else {
|
|
2730
2895
|
// If refValueType is not set, ensure it's null
|
|
@@ -2742,7 +2907,7 @@ async function writePropertyToDb(propertyFileId, data, isEdited = false) {
|
|
|
2742
2907
|
.update(properties)
|
|
2743
2908
|
.set(propertyData)
|
|
2744
2909
|
.where(drizzleOrm.eq(properties.id, existing.id));
|
|
2745
|
-
logger$
|
|
2910
|
+
logger$y(`Updated property ${data.name} (${propertyFileId}) in database`);
|
|
2746
2911
|
}
|
|
2747
2912
|
else {
|
|
2748
2913
|
// Property doesn't exist, create it
|
|
@@ -2758,17 +2923,17 @@ async function writePropertyToDb(propertyFileId, data, isEdited = false) {
|
|
|
2758
2923
|
.update(properties)
|
|
2759
2924
|
.set(propertyData)
|
|
2760
2925
|
.where(drizzleOrm.eq(properties.id, doubleCheck[0].id));
|
|
2761
|
-
logger$
|
|
2926
|
+
logger$y(`Property with schemaFileId "${propertyFileId}" was created by another process, updated existing record`);
|
|
2762
2927
|
}
|
|
2763
2928
|
else {
|
|
2764
2929
|
try {
|
|
2765
2930
|
await db.insert(properties).values(propertyData);
|
|
2766
|
-
logger$
|
|
2931
|
+
logger$y(`Created property ${data.name} (${propertyFileId}) in database`);
|
|
2767
2932
|
}
|
|
2768
2933
|
catch (error) {
|
|
2769
2934
|
// Handle unique constraint violation
|
|
2770
2935
|
if (isSqliteUniqueConstraintError(error)) {
|
|
2771
|
-
logger$
|
|
2936
|
+
logger$y(`Unique constraint violation for property schemaFileId "${propertyFileId}", attempting to find existing property`);
|
|
2772
2937
|
const existing = await db
|
|
2773
2938
|
.select()
|
|
2774
2939
|
.from(properties)
|
|
@@ -2779,7 +2944,7 @@ async function writePropertyToDb(propertyFileId, data, isEdited = false) {
|
|
|
2779
2944
|
.update(properties)
|
|
2780
2945
|
.set(propertyData)
|
|
2781
2946
|
.where(drizzleOrm.eq(properties.id, existing[0].id));
|
|
2782
|
-
logger$
|
|
2947
|
+
logger$y(`Found existing property with schemaFileId "${propertyFileId}" (id: ${existing[0].id}) after constraint violation, updated it`);
|
|
2783
2948
|
}
|
|
2784
2949
|
else {
|
|
2785
2950
|
throw new Error(`Failed to create or find property "${data.name}" with schemaFileId "${propertyFileId}": ${error.message}`);
|
|
@@ -2962,6 +3127,7 @@ var db = /*#__PURE__*/Object.freeze({
|
|
|
2962
3127
|
getObjectForRow: getObjectForRow,
|
|
2963
3128
|
getOwnedAddressesFromDb: getOwnedAddressesFromDb,
|
|
2964
3129
|
getPropertyIdForModelAndName: getPropertyIdForModelAndName,
|
|
3130
|
+
getPropertyIdForSchemaFileId: getPropertyIdForSchemaFileId,
|
|
2965
3131
|
getPropertyModelNameAndDataType: getPropertyModelNameAndDataType,
|
|
2966
3132
|
getSchemaId: getSchemaId,
|
|
2967
3133
|
getSchemaIdByFileId: getSchemaIdByFileId,
|
|
@@ -3053,7 +3219,7 @@ const supportsOpfsFileDownloads = () => {
|
|
|
3053
3219
|
return isBrowser() || isElectronRenderer();
|
|
3054
3220
|
};
|
|
3055
3221
|
|
|
3056
|
-
const logger$
|
|
3222
|
+
const logger$x = debug('seedSdk:files:download');
|
|
3057
3223
|
const AUTO_BULK_DOWNLOAD_THROTTLE_MS = 10000;
|
|
3058
3224
|
/** Avoid refetch-on-every-call: transient empty indexer responses were overwriting good cache (see trailing throttle ~10s after success). */
|
|
3059
3225
|
const GET_FILES_METADATA_STALE_MS = 120000;
|
|
@@ -3063,7 +3229,7 @@ const lazyDownloadInFlightByTransactionId = new Map();
|
|
|
3063
3229
|
const syncDbFiles = async (endpoints) => {
|
|
3064
3230
|
// TODO: Implement syncDbFiles functionality if needed
|
|
3065
3231
|
// This was previously in @/services/internal/helpers
|
|
3066
|
-
logger$
|
|
3232
|
+
logger$x('[download] syncDbFiles called but not yet implemented');
|
|
3067
3233
|
return Promise.resolve();
|
|
3068
3234
|
};
|
|
3069
3235
|
const getAppDbReady = async () => {
|
|
@@ -3249,16 +3415,19 @@ const downloadTransactionIds = async (rawTransactionIds, options) => {
|
|
|
3249
3415
|
transactionIdsToDownload.push(transactionId);
|
|
3250
3416
|
}
|
|
3251
3417
|
catch (error) {
|
|
3252
|
-
logger$
|
|
3418
|
+
logger$x(error);
|
|
3253
3419
|
}
|
|
3254
3420
|
}
|
|
3255
3421
|
if (transactionIdsToDownload.length === 0) {
|
|
3256
3422
|
return false;
|
|
3257
3423
|
}
|
|
3424
|
+
// Preferred gateways first: a just-published item is only on the gateway it was uploaded through.
|
|
3425
|
+
const arweaveBaseUrls = arweave.getArweaveReadBaseUrls();
|
|
3258
3426
|
if (transactionIdsToDownload.length === 1) {
|
|
3259
3427
|
await BaseFileManager.downloadFileByTransactionId({
|
|
3260
3428
|
transactionId: transactionIdsToDownload[0],
|
|
3261
3429
|
arweaveHost: arweave.BaseArweaveClient.getBaseUrl(),
|
|
3430
|
+
arweaveBaseUrls,
|
|
3262
3431
|
excludedTransactions,
|
|
3263
3432
|
});
|
|
3264
3433
|
}
|
|
@@ -3266,6 +3435,7 @@ const downloadTransactionIds = async (rawTransactionIds, options) => {
|
|
|
3266
3435
|
await BaseFileManager.downloadAllFiles({
|
|
3267
3436
|
transactionIds: transactionIdsToDownload,
|
|
3268
3437
|
arweaveHost: arweave.BaseArweaveClient.getBaseUrl(),
|
|
3438
|
+
arweaveBaseUrls,
|
|
3269
3439
|
excludedTransactions,
|
|
3270
3440
|
});
|
|
3271
3441
|
}
|
|
@@ -3382,7 +3552,7 @@ const downloadTransactionIdWithDedupe = async (transactionId) => {
|
|
|
3382
3552
|
};
|
|
3383
3553
|
const scheduleBulkFilesDownloadFromEasSyncThrottled = lodashEs.throttle((addressesHint) => {
|
|
3384
3554
|
void downloadAllFilesBinaryRequestHandler(addressesHint).catch((error) => {
|
|
3385
|
-
logger$
|
|
3555
|
+
logger$x('[scheduleBulkFilesDownloadFromEasSync] failed', error);
|
|
3386
3556
|
});
|
|
3387
3557
|
}, AUTO_BULK_DOWNLOAD_THROTTLE_MS, { leading: true, trailing: false });
|
|
3388
3558
|
const scheduleBulkFilesDownloadFromEasSync = (addressesHint) => {
|
|
@@ -3483,7 +3653,11 @@ const INTERNAL_PROPERTY_NAMES = [
|
|
|
3483
3653
|
// SDK-internal: Unix timestamp when attestations were revoked; never a schema field
|
|
3484
3654
|
'revokedAt',
|
|
3485
3655
|
];
|
|
3486
|
-
|
|
3656
|
+
/**
|
|
3657
|
+
* UID of {@link VERSION_SCHEMA_DEF}. Schema UIDs hash the definition, resolver and revocable flag,
|
|
3658
|
+
* so this is the same on every chain; the schema must still be registered on each one.
|
|
3659
|
+
*/
|
|
3660
|
+
const VERSION_SCHEMA_UID = '0x13c0fd59d69dbce40501a41f8b37768d26dd2e2bb0cad64615334d84f7b9bdf6';
|
|
3487
3661
|
const defaultAttestationData = {
|
|
3488
3662
|
recipient: ZERO_ADDRESS,
|
|
3489
3663
|
revocable: true,
|
|
@@ -3521,7 +3695,7 @@ function isInternalSchema(schemaName, schemaId) {
|
|
|
3521
3695
|
(schemaId !== undefined && INTERNAL_SCHEMA_IDS.includes(schemaId));
|
|
3522
3696
|
}
|
|
3523
3697
|
|
|
3524
|
-
const logger$
|
|
3698
|
+
const logger$w = debug('seedSdk:helpers:ensureImageLocal');
|
|
3525
3699
|
/** Arweave transaction ids are 43 chars in the URL-safe base64 alphabet. */
|
|
3526
3700
|
const ARWEAVE_TX_ID_RE = /^[a-z0-9_-]{43}$/i;
|
|
3527
3701
|
const IMAGE_SIZES = [
|
|
@@ -3690,7 +3864,7 @@ const runEnsureImageLocal = async (params) => {
|
|
|
3690
3864
|
};
|
|
3691
3865
|
}
|
|
3692
3866
|
catch (error) {
|
|
3693
|
-
logger$
|
|
3867
|
+
logger$w('ensureImageLocal failed', error);
|
|
3694
3868
|
return { status: 'failed' };
|
|
3695
3869
|
}
|
|
3696
3870
|
};
|
|
@@ -3739,7 +3913,7 @@ var generateId$1 = /*#__PURE__*/Object.freeze({
|
|
|
3739
3913
|
generateId: generateId
|
|
3740
3914
|
});
|
|
3741
3915
|
|
|
3742
|
-
const logger$
|
|
3916
|
+
const logger$v = debug('seedSdk:shared:helpers');
|
|
3743
3917
|
const toSnakeCase = (str) => {
|
|
3744
3918
|
return str.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
|
|
3745
3919
|
};
|
|
@@ -3796,7 +3970,7 @@ const convertTxIdToImage = async (txId) => {
|
|
|
3796
3970
|
const imageFilePath = BaseFileManager.getFilesPath('images', txId);
|
|
3797
3971
|
const fileExists = await BaseFileManager.pathExists(imageFilePath);
|
|
3798
3972
|
if (!fileExists) {
|
|
3799
|
-
logger$
|
|
3973
|
+
logger$v(`[ItemView] [updateImage] ${imageFilePath} does not exist`);
|
|
3800
3974
|
return;
|
|
3801
3975
|
}
|
|
3802
3976
|
const buffer = await BaseFileManager.readFileAsBuffer(imageFilePath);
|
|
@@ -3825,7 +3999,7 @@ const convertTxIdToImage = async (txId) => {
|
|
|
3825
3999
|
return URL.createObjectURL(imageBlob);
|
|
3826
4000
|
};
|
|
3827
4001
|
|
|
3828
|
-
const logger$
|
|
4002
|
+
const logger$u = debug('seedSdk:model:actors:loadOrCreateModel');
|
|
3829
4003
|
/**
|
|
3830
4004
|
* Create ModelProperty instances for all property IDs to ensure they're cached
|
|
3831
4005
|
* This ensures that ModelProperty.getById() in Model.properties getter will find the instances
|
|
@@ -3836,10 +4010,10 @@ const createPropertyInstances = async (propertyFileIds) => {
|
|
|
3836
4010
|
return;
|
|
3837
4011
|
}
|
|
3838
4012
|
try {
|
|
3839
|
-
const mod = await Promise.resolve().then(function () { return require('./ModelProperty-
|
|
4013
|
+
const mod = await Promise.resolve().then(function () { return require('./ModelProperty-D9FGaGuE.js'); });
|
|
3840
4014
|
const ModelProperty = mod?.ModelProperty ?? mod?.default;
|
|
3841
4015
|
if (!ModelProperty) {
|
|
3842
|
-
logger$
|
|
4016
|
+
logger$u('createPropertyInstances: ModelProperty not available from dynamic import');
|
|
3843
4017
|
return;
|
|
3844
4018
|
}
|
|
3845
4019
|
// Create instances for all property IDs in parallel
|
|
@@ -3848,22 +4022,22 @@ const createPropertyInstances = async (propertyFileIds) => {
|
|
|
3848
4022
|
try {
|
|
3849
4023
|
const property = await ModelProperty.createById(propertyFileId);
|
|
3850
4024
|
if (property) {
|
|
3851
|
-
logger$
|
|
4025
|
+
logger$u(`Created/cached ModelProperty instance for propertyFileId "${propertyFileId}"`);
|
|
3852
4026
|
}
|
|
3853
4027
|
else {
|
|
3854
|
-
logger$
|
|
4028
|
+
logger$u(`ModelProperty.createById returned undefined for propertyFileId "${propertyFileId}" (may not exist in DB yet)`);
|
|
3855
4029
|
}
|
|
3856
4030
|
}
|
|
3857
4031
|
catch (error) {
|
|
3858
|
-
logger$
|
|
4032
|
+
logger$u(`Error creating ModelProperty instance for propertyFileId "${propertyFileId}": ${error}`);
|
|
3859
4033
|
// Don't throw - continue with other properties
|
|
3860
4034
|
}
|
|
3861
4035
|
});
|
|
3862
4036
|
await Promise.all(createPromises);
|
|
3863
|
-
logger$
|
|
4037
|
+
logger$u(`Finished creating/caching ${propertyFileIds.length} ModelProperty instances`);
|
|
3864
4038
|
}
|
|
3865
4039
|
catch (error) {
|
|
3866
|
-
logger$
|
|
4040
|
+
logger$u(`Error in createPropertyInstances: ${error}`);
|
|
3867
4041
|
// Don't throw - this is best-effort to pre-populate cache
|
|
3868
4042
|
}
|
|
3869
4043
|
};
|
|
@@ -3893,7 +4067,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
3893
4067
|
if (dbModels.length > 0) {
|
|
3894
4068
|
modelRecord = dbModels[0];
|
|
3895
4069
|
foundBySchemaFileId = true;
|
|
3896
|
-
logger$
|
|
4070
|
+
logger$u(`Found model "${modelName}" in database by schemaFileId "${schemaFileId}"`);
|
|
3897
4071
|
}
|
|
3898
4072
|
}
|
|
3899
4073
|
// If not found by ID, try by name
|
|
@@ -3920,16 +4094,16 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
3920
4094
|
// Access instanceCacheById via type assertion since it's protected
|
|
3921
4095
|
const cacheById = Model.instanceCacheById;
|
|
3922
4096
|
if (cacheById.has(dbSchemaFileId)) {
|
|
3923
|
-
logger$
|
|
4097
|
+
logger$u(`Model "${modelName}" found in database by name with schemaFileId "${dbSchemaFileId}", and a cached instance already exists. Updating current instance to use the same schemaFileId.`);
|
|
3924
4098
|
// Update the current instance's schemaFileId to match the database
|
|
3925
4099
|
// This ensures both instances point to the same cached instance
|
|
3926
4100
|
modelRecord = foundModel;
|
|
3927
4101
|
schemaFileId = dbSchemaFileId;
|
|
3928
|
-
logger$
|
|
4102
|
+
logger$u(`Using existing cached instance with schemaFileId "${schemaFileId}" for model "${modelName}"`);
|
|
3929
4103
|
}
|
|
3930
4104
|
}
|
|
3931
4105
|
catch (error) {
|
|
3932
|
-
logger$
|
|
4106
|
+
logger$u(`Error checking Model cache for schemaFileId "${dbSchemaFileId}": ${error}`);
|
|
3933
4107
|
// Fall through to normal processing
|
|
3934
4108
|
}
|
|
3935
4109
|
}
|
|
@@ -3937,31 +4111,31 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
3937
4111
|
// this is a new model - don't use the existing model (will be renamed if duplicate)
|
|
3938
4112
|
// UNLESS we found a cached instance above (in which case modelRecord is already set)
|
|
3939
4113
|
if (!modelRecord && schemaFileId && dbSchemaFileId && schemaFileId !== dbSchemaFileId) {
|
|
3940
|
-
logger$
|
|
4114
|
+
logger$u(`Model "${modelName}" found by name but has different schemaFileId (provided: "${schemaFileId}", db: "${dbSchemaFileId}"). Creating new model (will check for duplicates).`);
|
|
3941
4115
|
// Don't set modelRecord - we'll create a new model with potentially renamed name
|
|
3942
4116
|
}
|
|
3943
4117
|
else if (!modelRecord && schemaFileId && !dbSchemaFileId) {
|
|
3944
4118
|
// We have a schemaFileId but the found model doesn't have one - this is a new model
|
|
3945
4119
|
// Don't reuse the existing model, create a new one (will be renamed if duplicate)
|
|
3946
|
-
logger$
|
|
4120
|
+
logger$u(`Model "${modelName}" found by name but found model has no schemaFileId. Creating new model with schemaFileId "${schemaFileId}" (will check for duplicates).`);
|
|
3947
4121
|
// Don't set modelRecord - we'll create a new model
|
|
3948
4122
|
}
|
|
3949
4123
|
else if (!modelRecord) {
|
|
3950
4124
|
// Only reuse existing model if:
|
|
3951
4125
|
// 1. No schemaFileId was provided (loading existing model), OR
|
|
3952
4126
|
// 2. schemaFileId matches (same model)
|
|
3953
|
-
logger$
|
|
4127
|
+
logger$u(`Model "${modelName}" found by name, reusing existing model (schemaFileId: provided="${schemaFileId}", db="${dbSchemaFileId}")`);
|
|
3954
4128
|
modelRecord = foundModel;
|
|
3955
4129
|
// Only use database schemaFileId if no id was explicitly provided
|
|
3956
4130
|
// If an id was provided, we should use it (it might be creating a new model with a specific ID)
|
|
3957
4131
|
if (!id && dbSchemaFileId) {
|
|
3958
4132
|
schemaFileId = dbSchemaFileId;
|
|
3959
|
-
logger$
|
|
4133
|
+
logger$u(`Using database schemaFileId "${schemaFileId}" for model "${modelName}" (no ID was provided)`);
|
|
3960
4134
|
}
|
|
3961
4135
|
else if (id) {
|
|
3962
|
-
logger$
|
|
4136
|
+
logger$u(`Preserving provided id (schemaFileId) "${schemaFileId}" for model "${modelName}" (ignoring database schemaFileId "${dbSchemaFileId}")`);
|
|
3963
4137
|
}
|
|
3964
|
-
logger$
|
|
4138
|
+
logger$u(`Found model "${modelName}" in database by name, schemaFileId: "${schemaFileId}"`);
|
|
3965
4139
|
}
|
|
3966
4140
|
}
|
|
3967
4141
|
}
|
|
@@ -3984,7 +4158,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
3984
4158
|
// Generate schemaFileId if not set
|
|
3985
4159
|
if (!schemaFileId) {
|
|
3986
4160
|
schemaFileId = generateId();
|
|
3987
|
-
logger$
|
|
4161
|
+
logger$u(`Generated id (schemaFileId) "${schemaFileId}" for model "${modelName}"`);
|
|
3988
4162
|
}
|
|
3989
4163
|
// Include _dbId from database record so properties can be created if needed
|
|
3990
4164
|
// Even if we found an existing model, we may still need to create properties
|
|
@@ -4013,14 +4187,14 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4013
4187
|
}
|
|
4014
4188
|
}
|
|
4015
4189
|
catch (error) {
|
|
4016
|
-
logger$
|
|
4190
|
+
logger$u(`Error loading model from database: ${error}`);
|
|
4017
4191
|
// Fall through to create new model
|
|
4018
4192
|
}
|
|
4019
4193
|
}
|
|
4020
4194
|
// Step 2: Fallback to Schema context (only if database doesn't have the model)
|
|
4021
4195
|
// This handles the case where model exists in schema file but not yet in database
|
|
4022
4196
|
try {
|
|
4023
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-
|
|
4197
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-BiJIPLEL.js'); });
|
|
4024
4198
|
const { Schema } = schemaMod;
|
|
4025
4199
|
const schema = Schema.create(schemaName, { waitForReady: false });
|
|
4026
4200
|
const schemaSnapshot = schema.getService().getSnapshot();
|
|
@@ -4048,10 +4222,10 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4048
4222
|
const byName = schemaContext.models[modelName];
|
|
4049
4223
|
const schemaModelId = byName?.id ?? null;
|
|
4050
4224
|
if (schemaFileId === schemaModelId) {
|
|
4051
|
-
logger$
|
|
4225
|
+
logger$u(`Found model "${modelName}" in Schema context (database fallback)`);
|
|
4052
4226
|
if (!schemaFileId) {
|
|
4053
4227
|
schemaFileId = generateId();
|
|
4054
|
-
logger$
|
|
4228
|
+
logger$u(`Generated id (schemaFileId) "${schemaFileId}" for model "${modelName}"`);
|
|
4055
4229
|
}
|
|
4056
4230
|
sendBack({
|
|
4057
4231
|
type: 'loadOrCreateModelSuccess',
|
|
@@ -4067,7 +4241,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4067
4241
|
// Schema context may not have model by name yet (e.g. still loading). If our id appears in any schema model, we're the schema model.
|
|
4068
4242
|
for (const def of Object.values(schemaContext.models)) {
|
|
4069
4243
|
if (def?.id === schemaFileId) {
|
|
4070
|
-
logger$
|
|
4244
|
+
logger$u(`Found model in Schema context by id "${schemaFileId}" (database fallback)`);
|
|
4071
4245
|
sendBack({
|
|
4072
4246
|
type: 'loadOrCreateModelSuccess',
|
|
4073
4247
|
model: { id: schemaFileId },
|
|
@@ -4079,7 +4253,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4079
4253
|
}
|
|
4080
4254
|
}
|
|
4081
4255
|
catch (error) {
|
|
4082
|
-
logger$
|
|
4256
|
+
logger$u(`Error loading model from Schema context: ${error}`);
|
|
4083
4257
|
// Fall through to create new model
|
|
4084
4258
|
}
|
|
4085
4259
|
// Step 3: Check for duplicate names in database before creating new model
|
|
@@ -4099,7 +4273,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4099
4273
|
// 3. This is an internal schema (internal schemas should preserve original names from schema files), OR
|
|
4100
4274
|
// 4. This instance was created with modelFileId from schema (_idFromSchema) - schema models keep their name
|
|
4101
4275
|
const shouldSkipDuplicateCheck = modelRecord !== null || foundBySchemaFileId || isInternal || !!_idFromSchema;
|
|
4102
|
-
logger$
|
|
4276
|
+
logger$u(`Duplicate check: modelRecord=${modelRecord !== null}, foundBySchemaFileId=${foundBySchemaFileId}, isInternal=${isInternal}, _idFromSchema=${!!_idFromSchema}, schemaFileId=${schemaFileId}, shouldSkip=${shouldSkipDuplicateCheck}`);
|
|
4103
4277
|
if (!shouldSkipDuplicateCheck) {
|
|
4104
4278
|
try {
|
|
4105
4279
|
const lowerModelName = modelName.toLowerCase();
|
|
@@ -4111,7 +4285,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4111
4285
|
// Check name-based cache for this schema
|
|
4112
4286
|
// Skip the current model (context.id): Model.create() adds the new instance to the cache
|
|
4113
4287
|
// before this callback runs, so we must not count it as a duplicate.
|
|
4114
|
-
logger$
|
|
4288
|
+
logger$u(`Checking Model cache for duplicates in schema "${schemaName}"`);
|
|
4115
4289
|
const currentModelFileId = schemaFileId ?? null;
|
|
4116
4290
|
const cacheByName = Model.instanceCacheByName;
|
|
4117
4291
|
for (const [nameKey, cachedModelFileId] of cacheByName.entries()) {
|
|
@@ -4122,7 +4296,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4122
4296
|
const lowerCachedName = cachedModelName.toLowerCase();
|
|
4123
4297
|
if (lowerCachedName === lowerModelName) {
|
|
4124
4298
|
existingNumbers.add(0); // Base name exists
|
|
4125
|
-
logger$
|
|
4299
|
+
logger$u(`Found duplicate in Model cache: "${cachedModelName}" matches "${modelName}"`);
|
|
4126
4300
|
}
|
|
4127
4301
|
else if (lowerCachedName.startsWith(lowerModelName + ' ')) {
|
|
4128
4302
|
// Check if it's the base name followed by a space and a number
|
|
@@ -4130,7 +4304,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4130
4304
|
const number = parseInt(suffix, 10);
|
|
4131
4305
|
if (!isNaN(number) && suffix === number.toString()) {
|
|
4132
4306
|
existingNumbers.add(number);
|
|
4133
|
-
logger$
|
|
4307
|
+
logger$u(`Found numbered variant in Model cache: "${cachedModelName}" (number: ${number})`);
|
|
4134
4308
|
}
|
|
4135
4309
|
}
|
|
4136
4310
|
}
|
|
@@ -4146,7 +4320,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4146
4320
|
const lowerCachedName = cachedModelName.toLowerCase();
|
|
4147
4321
|
if (lowerCachedName === lowerModelName) {
|
|
4148
4322
|
existingNumbers.add(0); // Base name exists
|
|
4149
|
-
logger$
|
|
4323
|
+
logger$u(`Found duplicate in Model legacy cache: "${cachedModelName}" matches "${modelName}"`);
|
|
4150
4324
|
}
|
|
4151
4325
|
else if (lowerCachedName.startsWith(lowerModelName + ' ')) {
|
|
4152
4326
|
// Check if it's the base name followed by a space and a number
|
|
@@ -4154,14 +4328,14 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4154
4328
|
const number = parseInt(suffix, 10);
|
|
4155
4329
|
if (!isNaN(number) && suffix === number.toString()) {
|
|
4156
4330
|
existingNumbers.add(number);
|
|
4157
|
-
logger$
|
|
4331
|
+
logger$u(`Found numbered variant in Model legacy cache: "${cachedModelName}" (number: ${number})`);
|
|
4158
4332
|
}
|
|
4159
4333
|
}
|
|
4160
4334
|
}
|
|
4161
4335
|
}
|
|
4162
4336
|
}
|
|
4163
4337
|
catch (error) {
|
|
4164
|
-
logger$
|
|
4338
|
+
logger$u(`Error checking Model cache for duplicates: ${error}`);
|
|
4165
4339
|
// Continue with database check
|
|
4166
4340
|
}
|
|
4167
4341
|
// Also check database for models (in case they're persisted but not in Schema context)
|
|
@@ -4171,7 +4345,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4171
4345
|
const schemaSchemaMod = await Promise.resolve().then(function () { return SchemaSchema; });
|
|
4172
4346
|
const { schemas: schemasTable } = schemaSchemaMod;
|
|
4173
4347
|
// Query all models for this schema to check for duplicates (case-insensitive)
|
|
4174
|
-
logger$
|
|
4348
|
+
logger$u(`Checking database for duplicate model names in schema "${schemaName}"`);
|
|
4175
4349
|
const allModelsForSchema = await db
|
|
4176
4350
|
.select({
|
|
4177
4351
|
name: models$1.name,
|
|
@@ -4180,16 +4354,16 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4180
4354
|
.innerJoin(modelSchemas, drizzleOrm.eq(models$1.id, modelSchemas.modelId))
|
|
4181
4355
|
.innerJoin(schemasTable, drizzleOrm.eq(modelSchemas.schemaId, schemasTable.id))
|
|
4182
4356
|
.where(drizzleOrm.eq(schemasTable.name, schemaName));
|
|
4183
|
-
logger$
|
|
4357
|
+
logger$u(`Found ${allModelsForSchema.length} models in database for schema "${schemaName}": ${allModelsForSchema.map((m) => m.name).join(', ')}`);
|
|
4184
4358
|
if (allModelsForSchema.length === 0 && modelName.includes('Shared')) {
|
|
4185
|
-
logger$
|
|
4359
|
+
logger$u(`[DEBUG] No models found in database for schema "${schemaName}" when checking for duplicate "${modelName}"`);
|
|
4186
4360
|
}
|
|
4187
4361
|
// Check for exact match (case-insensitive) or matches with number suffix
|
|
4188
4362
|
for (const dbModel of allModelsForSchema) {
|
|
4189
4363
|
const lowerDbName = dbModel.name.toLowerCase();
|
|
4190
4364
|
if (lowerDbName === lowerModelName) {
|
|
4191
4365
|
existingNumbers.add(0); // Base name exists
|
|
4192
|
-
logger$
|
|
4366
|
+
logger$u(`Found duplicate in database: "${dbModel.name}" matches "${modelName}"`);
|
|
4193
4367
|
}
|
|
4194
4368
|
else if (lowerDbName.startsWith(lowerModelName + ' ')) {
|
|
4195
4369
|
// Check if it's the base name followed by a space and a number
|
|
@@ -4197,48 +4371,48 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4197
4371
|
const number = parseInt(suffix, 10);
|
|
4198
4372
|
if (!isNaN(number) && suffix === number.toString()) {
|
|
4199
4373
|
existingNumbers.add(number);
|
|
4200
|
-
logger$
|
|
4374
|
+
logger$u(`Found numbered variant in database: "${dbModel.name}" (number: ${number})`);
|
|
4201
4375
|
}
|
|
4202
4376
|
}
|
|
4203
4377
|
}
|
|
4204
4378
|
}
|
|
4205
4379
|
// If duplicates found, generate unique name
|
|
4206
|
-
logger$
|
|
4380
|
+
logger$u(`Duplicate check results: existingNumbers=${Array.from(existingNumbers).join(', ')}, hasBaseName=${existingNumbers.has(0)}`);
|
|
4207
4381
|
if (existingNumbers.has(0)) {
|
|
4208
4382
|
let nextNumber = 1;
|
|
4209
4383
|
while (existingNumbers.has(nextNumber)) {
|
|
4210
4384
|
nextNumber++;
|
|
4211
4385
|
}
|
|
4212
4386
|
finalModelName = `${modelName} ${nextNumber}`;
|
|
4213
|
-
logger$
|
|
4387
|
+
logger$u(`Found duplicate model name "${modelName}" in schema "${schemaName}", using unique name "${finalModelName}"`);
|
|
4214
4388
|
}
|
|
4215
4389
|
else {
|
|
4216
|
-
logger$
|
|
4390
|
+
logger$u(`No duplicate found for model name "${modelName}" in schema "${schemaName}"`);
|
|
4217
4391
|
}
|
|
4218
4392
|
}
|
|
4219
4393
|
catch (error) {
|
|
4220
|
-
logger$
|
|
4394
|
+
logger$u(`Error checking for duplicate model names: ${error}`);
|
|
4221
4395
|
// Continue with original name if check fails
|
|
4222
4396
|
}
|
|
4223
4397
|
}
|
|
4224
4398
|
else {
|
|
4225
4399
|
if (foundBySchemaFileId) {
|
|
4226
|
-
logger$
|
|
4400
|
+
logger$u(`Preserving original model name "${modelName}" for model found by schemaFileId (schemaFileId: ${schemaFileId})`);
|
|
4227
4401
|
}
|
|
4228
4402
|
else if (modelRecord) {
|
|
4229
|
-
logger$
|
|
4403
|
+
logger$u(`Using existing model name "${modelName}" from database (modelRecord found)`);
|
|
4230
4404
|
}
|
|
4231
4405
|
else if (isInternal) {
|
|
4232
|
-
logger$
|
|
4406
|
+
logger$u(`Preserving original model name "${modelName}" for internal schema "${schemaName}" (skipping duplicate check)`);
|
|
4233
4407
|
}
|
|
4234
4408
|
}
|
|
4235
4409
|
}
|
|
4236
4410
|
// Step 4: Create new empty model (not found in database or Schema context)
|
|
4237
|
-
logger$
|
|
4411
|
+
logger$u(`Creating new model "${finalModelName}" in schema "${schemaName}"`);
|
|
4238
4412
|
// Generate schemaFileId for new model
|
|
4239
4413
|
if (!schemaFileId) {
|
|
4240
4414
|
schemaFileId = generateId();
|
|
4241
|
-
logger$
|
|
4415
|
+
logger$u(`Generated id (schemaFileId) "${schemaFileId}" for new model "${finalModelName}"`);
|
|
4242
4416
|
}
|
|
4243
4417
|
// Runtime creates use a placeholder cache key in Model.create; move it to the final name. Skip when schema model (_idFromSchema).
|
|
4244
4418
|
if (!_idFromSchema) {
|
|
@@ -4250,7 +4424,7 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4250
4424
|
// This avoids the issue where updateContext with modelName triggers validation and state transition
|
|
4251
4425
|
// We use _pendingModelName (internal field) which won't trigger validation
|
|
4252
4426
|
if (finalModelName !== modelName) {
|
|
4253
|
-
logger$
|
|
4427
|
+
logger$u(`Model name changed from "${modelName}" to "${finalModelName}", storing in _pendingModelName for loadOrCreateModelSuccess`);
|
|
4254
4428
|
// Store the final name in a temporary internal field that will be picked up by loadOrCreateModelSuccess
|
|
4255
4429
|
sendBack({
|
|
4256
4430
|
type: 'updateContext',
|
|
@@ -4258,17 +4432,17 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4258
4432
|
});
|
|
4259
4433
|
}
|
|
4260
4434
|
else {
|
|
4261
|
-
logger$
|
|
4435
|
+
logger$u(`Model name unchanged: "${modelName}"`);
|
|
4262
4436
|
}
|
|
4263
4437
|
// Mark schema as draft when a new model is created so saveNewVersion() can persist it
|
|
4264
4438
|
try {
|
|
4265
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-
|
|
4439
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-BiJIPLEL.js'); });
|
|
4266
4440
|
const { Schema } = schemaMod;
|
|
4267
4441
|
const schema = Schema.create(schemaName, { waitForReady: false });
|
|
4268
4442
|
schema.getService().send({ type: 'markAsDraft', propertyKey: 'schema:models' });
|
|
4269
4443
|
}
|
|
4270
4444
|
catch (err) {
|
|
4271
|
-
logger$
|
|
4445
|
+
logger$u(`Failed to mark schema as draft after creating model: ${err}`);
|
|
4272
4446
|
}
|
|
4273
4447
|
sendBack({
|
|
4274
4448
|
type: 'loadOrCreateModelSuccess',
|
|
@@ -4278,12 +4452,12 @@ const loadOrCreateModel = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
4278
4452
|
});
|
|
4279
4453
|
};
|
|
4280
4454
|
_loadOrCreateModel().catch((error) => {
|
|
4281
|
-
logger$
|
|
4455
|
+
logger$u('Error loading or creating model:', error);
|
|
4282
4456
|
sendBack({ type: 'loadOrCreateModelError', error });
|
|
4283
4457
|
});
|
|
4284
4458
|
});
|
|
4285
4459
|
|
|
4286
|
-
const logger$
|
|
4460
|
+
const logger$t = debug('seedSdk:model:actors:validateModel');
|
|
4287
4461
|
// Validation timeout in milliseconds (10 seconds)
|
|
4288
4462
|
const VALIDATION_TIMEOUT_MS = 10000;
|
|
4289
4463
|
const validateModel = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
@@ -4306,10 +4480,10 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
4306
4480
|
const _validateModel = async () => {
|
|
4307
4481
|
try {
|
|
4308
4482
|
// Use dynamic imports to break circular dependencies
|
|
4309
|
-
const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-
|
|
4483
|
+
const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-DtYs_CNY.js'); });
|
|
4310
4484
|
const { SchemaValidationService } = validationServiceMod;
|
|
4311
4485
|
const validationService = new SchemaValidationService();
|
|
4312
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-
|
|
4486
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-BiJIPLEL.js'); });
|
|
4313
4487
|
const { Schema } = schemaMod;
|
|
4314
4488
|
// Validate model structure
|
|
4315
4489
|
const structureResult = validationService.validateModelStructure(context);
|
|
@@ -4350,12 +4524,12 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
4350
4524
|
}
|
|
4351
4525
|
}
|
|
4352
4526
|
else {
|
|
4353
|
-
logger$
|
|
4527
|
+
logger$t(`Schema is in ${schemaStatus} state, skipping schema validation`);
|
|
4354
4528
|
// Continue with structure validation only
|
|
4355
4529
|
}
|
|
4356
4530
|
}
|
|
4357
4531
|
catch (error) {
|
|
4358
|
-
logger$
|
|
4532
|
+
logger$t('Error validating model against schema:', error);
|
|
4359
4533
|
// Continue with structure validation only
|
|
4360
4534
|
}
|
|
4361
4535
|
}
|
|
@@ -4370,7 +4544,7 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
4370
4544
|
if (!hasResponded) {
|
|
4371
4545
|
hasResponded = true;
|
|
4372
4546
|
clearTimeout(timeoutId);
|
|
4373
|
-
logger$
|
|
4547
|
+
logger$t('Error in validateModel:', error);
|
|
4374
4548
|
sendBack({
|
|
4375
4549
|
type: 'validationError',
|
|
4376
4550
|
errors: [{
|
|
@@ -4387,7 +4561,7 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
4387
4561
|
if (!hasResponded) {
|
|
4388
4562
|
hasResponded = true;
|
|
4389
4563
|
clearTimeout(timeoutId);
|
|
4390
|
-
logger$
|
|
4564
|
+
logger$t('Error in validateModel:', error);
|
|
4391
4565
|
sendBack({
|
|
4392
4566
|
type: 'validationError',
|
|
4393
4567
|
errors: [{
|
|
@@ -4405,7 +4579,7 @@ const validateModel = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
4405
4579
|
};
|
|
4406
4580
|
});
|
|
4407
4581
|
|
|
4408
|
-
const logger$
|
|
4582
|
+
const logger$s = debug('seedSdk:model:actors:createModelProperties');
|
|
4409
4583
|
const createModelProperties = xstate.fromCallback(({ sendBack, input }) => {
|
|
4410
4584
|
const _createProperties = async () => {
|
|
4411
4585
|
const { context, propertyDefinitions } = input;
|
|
@@ -4414,15 +4588,15 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4414
4588
|
throw new Error('Model ID, file ID, and name are required to create properties');
|
|
4415
4589
|
}
|
|
4416
4590
|
if (!propertyDefinitions || Object.keys(propertyDefinitions).length === 0) {
|
|
4417
|
-
logger$
|
|
4591
|
+
logger$s('No property definitions provided, skipping property creation');
|
|
4418
4592
|
sendBack({ type: 'createModelPropertiesSuccess' });
|
|
4419
4593
|
return;
|
|
4420
4594
|
}
|
|
4421
|
-
logger$
|
|
4422
|
-
const mod = await Promise.resolve().then(function () { return require('./ModelProperty-
|
|
4595
|
+
logger$s(`Creating ${Object.keys(propertyDefinitions).length} properties for model "${modelName}" (id: ${_dbId})`);
|
|
4596
|
+
const mod = await Promise.resolve().then(function () { return require('./ModelProperty-D9FGaGuE.js'); });
|
|
4423
4597
|
const ModelProperty = mod?.ModelProperty ?? mod?.default;
|
|
4424
4598
|
if (!ModelProperty) {
|
|
4425
|
-
logger$
|
|
4599
|
+
logger$s('ModelProperty not available from dynamic import');
|
|
4426
4600
|
sendBack({ type: 'createModelPropertiesError', error: new Error('ModelProperty not available') });
|
|
4427
4601
|
return;
|
|
4428
4602
|
}
|
|
@@ -4434,7 +4608,7 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4434
4608
|
// IDs should be generated in the import process before creating properties
|
|
4435
4609
|
const { generateId } = await Promise.resolve().then(function () { return generateId$1; });
|
|
4436
4610
|
const propertyFileId = propData.id || generateId();
|
|
4437
|
-
logger$
|
|
4611
|
+
logger$s(`Creating property "${propName}" with fileId "${propertyFileId}"`);
|
|
4438
4612
|
// Query database to get refModelId if the property has ref/refModelName
|
|
4439
4613
|
// The property should already be in DB from addModelsToDb
|
|
4440
4614
|
let refModelId = propData.refModelId;
|
|
@@ -4449,7 +4623,7 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4449
4623
|
.limit(1);
|
|
4450
4624
|
if (propertyRecords.length > 0 && propertyRecords[0].refModelId) {
|
|
4451
4625
|
refModelId = propertyRecords[0].refModelId;
|
|
4452
|
-
logger$
|
|
4626
|
+
logger$s(`Found refModelId ${refModelId} from database for property "${propName}"`);
|
|
4453
4627
|
}
|
|
4454
4628
|
else if (refModelName) {
|
|
4455
4629
|
// Fallback: query models table directly by name
|
|
@@ -4460,12 +4634,12 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4460
4634
|
.limit(1);
|
|
4461
4635
|
if (refModelRecords.length > 0 && refModelRecords[0].id) {
|
|
4462
4636
|
refModelId = refModelRecords[0].id;
|
|
4463
|
-
logger$
|
|
4637
|
+
logger$s(`Resolved refModelId ${refModelId} from model name "${refModelName}" for property "${propName}"`);
|
|
4464
4638
|
}
|
|
4465
4639
|
}
|
|
4466
4640
|
}
|
|
4467
4641
|
catch (error) {
|
|
4468
|
-
logger$
|
|
4642
|
+
logger$s(`Error fetching refModelId for property "${propName}":`, error);
|
|
4469
4643
|
// Continue without refModelId - it will be resolved later in _initializeOriginalValues
|
|
4470
4644
|
}
|
|
4471
4645
|
}
|
|
@@ -4490,11 +4664,11 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4490
4664
|
_propertyFileId: propertyFileId, // Store schemaFileId for getById() lookups
|
|
4491
4665
|
}); // Use 'as any' because _propertyFileId is not in TProperty type
|
|
4492
4666
|
}
|
|
4493
|
-
logger$
|
|
4667
|
+
logger$s(`Successfully created all properties for model "${modelName}"`);
|
|
4494
4668
|
sendBack({ type: 'createModelPropertiesSuccess' });
|
|
4495
4669
|
};
|
|
4496
4670
|
_createProperties().catch((error) => {
|
|
4497
|
-
logger$
|
|
4671
|
+
logger$s(`Error creating model properties: ${error}`);
|
|
4498
4672
|
sendBack({
|
|
4499
4673
|
type: 'createModelPropertiesError',
|
|
4500
4674
|
error: error instanceof Error ? error : new Error(String(error))
|
|
@@ -4505,7 +4679,7 @@ const createModelProperties = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4505
4679
|
};
|
|
4506
4680
|
});
|
|
4507
4681
|
|
|
4508
|
-
const logger$
|
|
4682
|
+
const logger$r = debug('seedSdk:write:validateEntity');
|
|
4509
4683
|
// XState v5 type inference bug: fromPromise types are inverted
|
|
4510
4684
|
// We use type assertion to work around this
|
|
4511
4685
|
const validateEntity = xstate.fromPromise(async ({ input }) => {
|
|
@@ -4515,20 +4689,20 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
|
|
|
4515
4689
|
const _validate = async () => {
|
|
4516
4690
|
try {
|
|
4517
4691
|
const msg = `[validateEntity] Starting validation for ${entityInput.entityType}`;
|
|
4518
|
-
logger$
|
|
4519
|
-
logger$
|
|
4692
|
+
logger$r(msg);
|
|
4693
|
+
logger$r(`[validateEntity] Entity data:`, entityInput.entityData);
|
|
4520
4694
|
let result = { isValid: true, errors: [] };
|
|
4521
4695
|
if (entityInput.entityType === 'model') {
|
|
4522
4696
|
const structureMsg = `[validateEntity] Validating model structure`;
|
|
4523
|
-
logger$
|
|
4697
|
+
logger$r(structureMsg);
|
|
4524
4698
|
// Use existing Model validation
|
|
4525
|
-
const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-
|
|
4699
|
+
const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-DtYs_CNY.js'); });
|
|
4526
4700
|
const { SchemaValidationService } = validationServiceMod;
|
|
4527
4701
|
const validationService = new SchemaValidationService();
|
|
4528
4702
|
// Validate model structure
|
|
4529
4703
|
const structureResult = validationService.validateModelStructure(entityInput.entityData);
|
|
4530
4704
|
const structureResultMsg = `[validateEntity] Structure validation result: isValid=${structureResult.isValid}, errors=${structureResult.errors?.length || 0}`;
|
|
4531
|
-
logger$
|
|
4705
|
+
logger$r(structureResultMsg);
|
|
4532
4706
|
if (!structureResult.isValid) {
|
|
4533
4707
|
result = {
|
|
4534
4708
|
isValid: false,
|
|
@@ -4539,20 +4713,20 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
|
|
|
4539
4713
|
// If schema name provided, validate against schema
|
|
4540
4714
|
if (entityInput.entityData.schemaName) {
|
|
4541
4715
|
try {
|
|
4542
|
-
logger$
|
|
4543
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-
|
|
4716
|
+
logger$r(`[validateEntity] Validating model against schema "${entityInput.entityData.schemaName}"`);
|
|
4717
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-BiJIPLEL.js'); });
|
|
4544
4718
|
const { Schema } = schemaMod;
|
|
4545
4719
|
const schema = Schema.create(entityInput.entityData.schemaName, {
|
|
4546
4720
|
waitForReady: false,
|
|
4547
4721
|
});
|
|
4548
4722
|
const schemaSnapshot = schema.getService().getSnapshot();
|
|
4549
4723
|
const schemaStatus = schemaSnapshot.value;
|
|
4550
|
-
logger$
|
|
4724
|
+
logger$r(`[validateEntity] Schema status: ${schemaStatus}`);
|
|
4551
4725
|
if (schemaStatus === 'idle') {
|
|
4552
4726
|
const schemaContext = schemaSnapshot.context;
|
|
4553
|
-
logger$
|
|
4727
|
+
logger$r(`[validateEntity] Running validateModelAgainstSchema`);
|
|
4554
4728
|
const schemaResult = validationService.validateModelAgainstSchema(schemaContext, entityInput.entityData.modelName, entityInput.entityData);
|
|
4555
|
-
logger$
|
|
4729
|
+
logger$r(`[validateEntity] Schema validation result:`, schemaResult);
|
|
4556
4730
|
if (!schemaResult.isValid) {
|
|
4557
4731
|
result = {
|
|
4558
4732
|
isValid: false,
|
|
@@ -4561,22 +4735,22 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
|
|
|
4561
4735
|
}
|
|
4562
4736
|
}
|
|
4563
4737
|
else {
|
|
4564
|
-
logger$
|
|
4738
|
+
logger$r(`[validateEntity] Schema not in idle state (${schemaStatus}), skipping schema validation`);
|
|
4565
4739
|
}
|
|
4566
4740
|
}
|
|
4567
4741
|
catch (error) {
|
|
4568
|
-
logger$
|
|
4742
|
+
logger$r('Error validating model against schema:', error);
|
|
4569
4743
|
// Continue with structure validation only
|
|
4570
4744
|
}
|
|
4571
4745
|
}
|
|
4572
4746
|
else {
|
|
4573
|
-
logger$
|
|
4747
|
+
logger$r(`[validateEntity] No schemaName provided, skipping schema validation`);
|
|
4574
4748
|
}
|
|
4575
4749
|
}
|
|
4576
4750
|
}
|
|
4577
4751
|
else if (entityInput.entityType === 'modelProperty') {
|
|
4578
4752
|
// Use existing ModelProperty validation
|
|
4579
|
-
const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-
|
|
4753
|
+
const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-DtYs_CNY.js'); });
|
|
4580
4754
|
const { SchemaValidationService } = validationServiceMod;
|
|
4581
4755
|
const validationService = new SchemaValidationService();
|
|
4582
4756
|
// Validate property structure
|
|
@@ -4591,7 +4765,7 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
|
|
|
4591
4765
|
// If schema name and model name provided, validate against schema
|
|
4592
4766
|
if (entityInput.entityData._schemaName && entityInput.entityData.modelName) {
|
|
4593
4767
|
try {
|
|
4594
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-
|
|
4768
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./Schema-BiJIPLEL.js'); });
|
|
4595
4769
|
const { Schema } = schemaMod;
|
|
4596
4770
|
const schema = Schema.create(entityInput.entityData._schemaName, {
|
|
4597
4771
|
waitForReady: false,
|
|
@@ -4612,7 +4786,7 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
|
|
|
4612
4786
|
}
|
|
4613
4787
|
}
|
|
4614
4788
|
catch (error) {
|
|
4615
|
-
logger$
|
|
4789
|
+
logger$r('Error validating property against schema:', error);
|
|
4616
4790
|
// Continue with structure validation only
|
|
4617
4791
|
}
|
|
4618
4792
|
}
|
|
@@ -4620,7 +4794,7 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
|
|
|
4620
4794
|
}
|
|
4621
4795
|
else if (entityInput.entityType === 'schema') {
|
|
4622
4796
|
// Schema validation - use existing validation
|
|
4623
|
-
const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-
|
|
4797
|
+
const validationServiceMod = await Promise.resolve().then(function () { return require('./SchemaValidationService-DtYs_CNY.js'); });
|
|
4624
4798
|
const { SchemaValidationService } = validationServiceMod;
|
|
4625
4799
|
const validationService = new SchemaValidationService();
|
|
4626
4800
|
const schemaResult = validationService.validateSchema(entityInput.entityData);
|
|
@@ -4633,14 +4807,14 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
|
|
|
4633
4807
|
}
|
|
4634
4808
|
// Return the result - fromPromise will automatically put this in event.output
|
|
4635
4809
|
const completeMsg = `[validateEntity] Validation complete: isValid=${result.isValid}, errors=${result.errors?.length || 0}`;
|
|
4636
|
-
logger$
|
|
4637
|
-
logger$
|
|
4810
|
+
logger$r(completeMsg);
|
|
4811
|
+
logger$r(`[validateEntity] Validation complete:`, result);
|
|
4638
4812
|
return result;
|
|
4639
4813
|
}
|
|
4640
4814
|
catch (error) {
|
|
4641
4815
|
const errorMsg = `[validateEntity] Error in validateEntity: ${error instanceof Error ? error.message : String(error)}`;
|
|
4642
|
-
logger$
|
|
4643
|
-
logger$
|
|
4816
|
+
logger$r(errorMsg);
|
|
4817
|
+
logger$r('Error in validateEntity:', error);
|
|
4644
4818
|
// Throw error - fromPromise will automatically create error.platform event
|
|
4645
4819
|
throw error;
|
|
4646
4820
|
}
|
|
@@ -4649,7 +4823,7 @@ const validateEntity = xstate.fromPromise(async ({ input }) => {
|
|
|
4649
4823
|
// @ts-ignore - XState v5 type inference bug: fromPromise incorrectly expects output type to match input type
|
|
4650
4824
|
});
|
|
4651
4825
|
|
|
4652
|
-
const logger$
|
|
4826
|
+
const logger$q = debug('seedSdk:write:writeToDatabase');
|
|
4653
4827
|
const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
|
|
4654
4828
|
const _write = async () => {
|
|
4655
4829
|
try {
|
|
@@ -4660,8 +4834,8 @@ const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4660
4834
|
let output = input.entityData;
|
|
4661
4835
|
if (input.entityType === 'model') {
|
|
4662
4836
|
const writeMsg = `Writing model to database: ${input.entityData.modelName} (schemaId: ${input.entityData.schemaId})`;
|
|
4663
|
-
logger$
|
|
4664
|
-
logger$
|
|
4837
|
+
logger$q(writeMsg);
|
|
4838
|
+
logger$q(`Writing model to database:`, {
|
|
4665
4839
|
modelFileId: input.entityId,
|
|
4666
4840
|
modelName: input.entityData.modelName,
|
|
4667
4841
|
schemaId: input.entityData.schemaId,
|
|
@@ -4686,14 +4860,14 @@ const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4686
4860
|
output = input.entityData;
|
|
4687
4861
|
}
|
|
4688
4862
|
const successMsg = `Successfully wrote model "${input.entityData.modelName}" to database`;
|
|
4689
|
-
logger$
|
|
4863
|
+
logger$q(successMsg);
|
|
4690
4864
|
}
|
|
4691
4865
|
else if (input.entityType === 'modelProperty') {
|
|
4692
4866
|
// Use current ModelProperty context when available so a user rename before the
|
|
4693
4867
|
// initial write completes is not overwritten by the stale requestWrite payload.
|
|
4694
4868
|
let dataToWrite = input.entityData;
|
|
4695
4869
|
try {
|
|
4696
|
-
const mod = await Promise.resolve().then(function () { return require('./ModelProperty-
|
|
4870
|
+
const mod = await Promise.resolve().then(function () { return require('./ModelProperty-D9FGaGuE.js'); });
|
|
4697
4871
|
const ModelProperty = mod?.ModelProperty ?? mod?.default;
|
|
4698
4872
|
if (ModelProperty && typeof ModelProperty.getById === 'function') {
|
|
4699
4873
|
const instance = ModelProperty.getById(input.entityId);
|
|
@@ -4735,7 +4909,7 @@ const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4735
4909
|
});
|
|
4736
4910
|
}
|
|
4737
4911
|
catch (error) {
|
|
4738
|
-
logger$
|
|
4912
|
+
logger$q('Error in writeToDatabase:', error);
|
|
4739
4913
|
sendBack({
|
|
4740
4914
|
type: 'writeError',
|
|
4741
4915
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
@@ -4743,7 +4917,7 @@ const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4743
4917
|
}
|
|
4744
4918
|
};
|
|
4745
4919
|
_write().catch((error) => {
|
|
4746
|
-
logger$
|
|
4920
|
+
logger$q('Error in writeToDatabase promise:', error);
|
|
4747
4921
|
sendBack({
|
|
4748
4922
|
type: 'writeError',
|
|
4749
4923
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
@@ -4754,7 +4928,7 @@ const writeToDatabase = xstate.fromCallback(({ sendBack, input }) => {
|
|
|
4754
4928
|
};
|
|
4755
4929
|
});
|
|
4756
4930
|
|
|
4757
|
-
const logger$
|
|
4931
|
+
const logger$p = debug('seedSdk:write:writeProcessMachine');
|
|
4758
4932
|
const writeProcessMachine = xstate.setup({
|
|
4759
4933
|
types: {
|
|
4760
4934
|
context: {},
|
|
@@ -4792,8 +4966,8 @@ const writeProcessMachine = xstate.setup({
|
|
|
4792
4966
|
writeStatus: 'validating',
|
|
4793
4967
|
}),
|
|
4794
4968
|
({ event, context }) => {
|
|
4795
|
-
logger$
|
|
4796
|
-
logger$
|
|
4969
|
+
logger$p(`[startWrite] Received startWrite for ${context.entityType} "${context.entityId}"`);
|
|
4970
|
+
logger$p(`[startWrite] Data:`, event.data);
|
|
4797
4971
|
},
|
|
4798
4972
|
],
|
|
4799
4973
|
},
|
|
@@ -4802,14 +4976,14 @@ const writeProcessMachine = xstate.setup({
|
|
|
4802
4976
|
validating: {
|
|
4803
4977
|
entry: ({ context }) => {
|
|
4804
4978
|
const msg = `[validating] Entering validating state for ${context.entityType} "${context.entityId}"`;
|
|
4805
|
-
logger$
|
|
4806
|
-
logger$
|
|
4979
|
+
logger$p(msg);
|
|
4980
|
+
logger$p(`[validating] Entity data:`, context.pendingWrite?.data || context.entityData);
|
|
4807
4981
|
},
|
|
4808
4982
|
invoke: {
|
|
4809
4983
|
src: 'validateEntity',
|
|
4810
4984
|
input: ({ context }) => {
|
|
4811
4985
|
const entityData = context.pendingWrite?.data || context.entityData;
|
|
4812
|
-
logger$
|
|
4986
|
+
logger$p(`[validating] Invoking validateEntity with:`, { entityType: context.entityType, entityData });
|
|
4813
4987
|
return {
|
|
4814
4988
|
entityType: context.entityType,
|
|
4815
4989
|
entityData,
|
|
@@ -4837,8 +5011,8 @@ const writeProcessMachine = xstate.setup({
|
|
|
4837
5011
|
return false;
|
|
4838
5012
|
}
|
|
4839
5013
|
const resultMsg = `[validating] Validation result: isValid=${result.isValid}, errors=${result.errors?.length || 0}`;
|
|
4840
|
-
logger$
|
|
4841
|
-
logger$
|
|
5014
|
+
logger$p(resultMsg);
|
|
5015
|
+
logger$p(`[validating] Validation result:`, result);
|
|
4842
5016
|
return result.isValid;
|
|
4843
5017
|
},
|
|
4844
5018
|
actions: [
|
|
@@ -4848,7 +5022,7 @@ const writeProcessMachine = xstate.setup({
|
|
|
4848
5022
|
}),
|
|
4849
5023
|
({ context }) => {
|
|
4850
5024
|
const msg = `[validating] Validation passed, transitioning to writing for ${context.entityType} "${context.entityId}"`;
|
|
4851
|
-
logger$
|
|
5025
|
+
logger$p(msg);
|
|
4852
5026
|
},
|
|
4853
5027
|
],
|
|
4854
5028
|
},
|
|
@@ -4868,7 +5042,7 @@ const writeProcessMachine = xstate.setup({
|
|
|
4868
5042
|
}),
|
|
4869
5043
|
({ context, event }) => {
|
|
4870
5044
|
const result = event.output;
|
|
4871
|
-
logger$
|
|
5045
|
+
logger$p(`[validating] Validation failed for ${context.entityType} "${context.entityId}":`, result.errors);
|
|
4872
5046
|
},
|
|
4873
5047
|
],
|
|
4874
5048
|
},
|
|
@@ -4882,7 +5056,7 @@ const writeProcessMachine = xstate.setup({
|
|
|
4882
5056
|
}),
|
|
4883
5057
|
({ context, event }) => {
|
|
4884
5058
|
const errorMsg = `[validating] Validation error for ${context.entityType} "${context.entityId}": ${event.error}`;
|
|
4885
|
-
logger$
|
|
5059
|
+
logger$p(errorMsg);
|
|
4886
5060
|
console.error(errorMsg, event.error); // Always log to console
|
|
4887
5061
|
},
|
|
4888
5062
|
],
|
|
@@ -4897,8 +5071,8 @@ const writeProcessMachine = xstate.setup({
|
|
|
4897
5071
|
src: 'writeToDatabase',
|
|
4898
5072
|
input: ({ context }) => {
|
|
4899
5073
|
const entityData = context.pendingWrite?.data || context.entityData;
|
|
4900
|
-
logger$
|
|
4901
|
-
logger$
|
|
5074
|
+
logger$p(`[writing] Calling writeToDatabase for ${context.entityType} "${context.entityId}"`);
|
|
5075
|
+
logger$p(`[writing] Entity data:`, entityData);
|
|
4902
5076
|
return {
|
|
4903
5077
|
entityType: context.entityType,
|
|
4904
5078
|
entityId: context.entityId,
|
|
@@ -4919,7 +5093,7 @@ const writeProcessMachine = xstate.setup({
|
|
|
4919
5093
|
},
|
|
4920
5094
|
}),
|
|
4921
5095
|
({ context }) => {
|
|
4922
|
-
logger$
|
|
5096
|
+
logger$p(`[writing] Write successful for ${context.entityType} "${context.entityId}"`);
|
|
4923
5097
|
},
|
|
4924
5098
|
],
|
|
4925
5099
|
},
|
|
@@ -4932,7 +5106,7 @@ const writeProcessMachine = xstate.setup({
|
|
|
4932
5106
|
retryCount: ({ context }) => context.retryCount + 1,
|
|
4933
5107
|
}),
|
|
4934
5108
|
({ context, event }) => {
|
|
4935
|
-
logger$
|
|
5109
|
+
logger$p(`[writing] Write error for ${context.entityType} "${context.entityId}":`, event.error);
|
|
4936
5110
|
},
|
|
4937
5111
|
],
|
|
4938
5112
|
},
|
|
@@ -4973,7 +5147,7 @@ const writeProcessMachine = xstate.setup({
|
|
|
4973
5147
|
},
|
|
4974
5148
|
});
|
|
4975
5149
|
|
|
4976
|
-
const logger$
|
|
5150
|
+
const logger$o = debug('seedSdk:model:modelMachine');
|
|
4977
5151
|
const modelMachine = xstate.setup({
|
|
4978
5152
|
types: {
|
|
4979
5153
|
context: {},
|
|
@@ -5073,23 +5247,23 @@ const modelMachine = xstate.setup({
|
|
|
5073
5247
|
// Create ModelProperty instances for any new property IDs
|
|
5074
5248
|
if (Array.isArray(newPropertyIds) && newPropertyIds.length > 0) {
|
|
5075
5249
|
// Import and create instances asynchronously (fire-and-forget)
|
|
5076
|
-
Promise.resolve().then(function () { return require('./ModelProperty-
|
|
5250
|
+
Promise.resolve().then(function () { return require('./ModelProperty-D9FGaGuE.js'); }).then(({ ModelProperty }) => {
|
|
5077
5251
|
const createPromises = newPropertyIds.map(async (propertyFileId) => {
|
|
5078
5252
|
try {
|
|
5079
5253
|
const property = await ModelProperty.createById(propertyFileId);
|
|
5080
5254
|
if (property) {
|
|
5081
|
-
logger$
|
|
5255
|
+
logger$o(`[modelMachine] Created/cached ModelProperty instance for propertyFileId "${propertyFileId}" after _liveQueryPropertyIds update`);
|
|
5082
5256
|
}
|
|
5083
5257
|
}
|
|
5084
5258
|
catch (error) {
|
|
5085
|
-
logger$
|
|
5259
|
+
logger$o(`[modelMachine] Error creating ModelProperty instance for propertyFileId "${propertyFileId}": ${error}`);
|
|
5086
5260
|
}
|
|
5087
5261
|
});
|
|
5088
5262
|
Promise.all(createPromises).catch((error) => {
|
|
5089
|
-
logger$
|
|
5263
|
+
logger$o(`[modelMachine] Error creating property instances: ${error}`);
|
|
5090
5264
|
});
|
|
5091
5265
|
}).catch((error) => {
|
|
5092
|
-
logger$
|
|
5266
|
+
logger$o(`[modelMachine] Error importing ModelProperty: ${error}`);
|
|
5093
5267
|
});
|
|
5094
5268
|
}
|
|
5095
5269
|
}, 0);
|
|
@@ -5174,11 +5348,11 @@ const modelMachine = xstate.setup({
|
|
|
5174
5348
|
target: 'idle',
|
|
5175
5349
|
actions: xstate.assign(({ context, event }) => {
|
|
5176
5350
|
const hasPendingProps = !!(context._pendingPropertyDefinitions && Object.keys(context._pendingPropertyDefinitions).length > 0);
|
|
5177
|
-
logger$
|
|
5351
|
+
logger$o(`[loadOrCreateModelSuccess] Preserving _pendingPropertyDefinitions: ${hasPendingProps} (${Object.keys(context._pendingPropertyDefinitions || {}).length} properties)`);
|
|
5178
5352
|
// Check if there's a pending model name update (set before this event to avoid validation trigger)
|
|
5179
5353
|
const finalModelName = context._pendingModelName || context.modelName;
|
|
5180
5354
|
if (context._pendingModelName) {
|
|
5181
|
-
logger$
|
|
5355
|
+
logger$o(`[loadOrCreateModelSuccess] Applying pending model name: "${context.modelName}" -> "${finalModelName}"`);
|
|
5182
5356
|
}
|
|
5183
5357
|
return {
|
|
5184
5358
|
...context,
|
|
@@ -5219,7 +5393,7 @@ const modelMachine = xstate.setup({
|
|
|
5219
5393
|
entry: xstate.assign({
|
|
5220
5394
|
writeProcess: ({ context, spawn }) => {
|
|
5221
5395
|
if (!context.writeProcess && context.id) {
|
|
5222
|
-
logger$
|
|
5396
|
+
logger$o(`[idle entry] Spawning writeProcess for model "${context.modelName}" (${context.id})`);
|
|
5223
5397
|
return spawn(writeProcessMachine, {
|
|
5224
5398
|
input: {
|
|
5225
5399
|
entityType: 'model',
|
|
@@ -5240,7 +5414,7 @@ const modelMachine = xstate.setup({
|
|
|
5240
5414
|
actions: ({ self }) => {
|
|
5241
5415
|
// This event will be handled by the Model instance's subscription
|
|
5242
5416
|
// The Model will call _refreshPropertiesFromDb when it receives this event
|
|
5243
|
-
logger$
|
|
5417
|
+
logger$o(`[idle] refreshProperties event received, will be handled by Model instance`);
|
|
5244
5418
|
},
|
|
5245
5419
|
},
|
|
5246
5420
|
validateModel: {
|
|
@@ -5252,14 +5426,14 @@ const modelMachine = xstate.setup({
|
|
|
5252
5426
|
requestWrite: {
|
|
5253
5427
|
actions: ({ context, event }) => {
|
|
5254
5428
|
if (context.writeProcess) {
|
|
5255
|
-
logger$
|
|
5429
|
+
logger$o(`[requestWrite] Sending startWrite to writeProcess with data:`, event.data);
|
|
5256
5430
|
context.writeProcess.send({
|
|
5257
5431
|
type: 'startWrite',
|
|
5258
5432
|
data: event.data,
|
|
5259
5433
|
});
|
|
5260
5434
|
}
|
|
5261
5435
|
else {
|
|
5262
|
-
logger$
|
|
5436
|
+
logger$o(`[requestWrite] ERROR: writeProcess not available for model "${context.modelName}" (${context.id})`);
|
|
5263
5437
|
}
|
|
5264
5438
|
},
|
|
5265
5439
|
},
|
|
@@ -5268,18 +5442,18 @@ const modelMachine = xstate.setup({
|
|
|
5268
5442
|
guard: ({ context }) => {
|
|
5269
5443
|
// If we have pending property definitions, transition to creatingProperties
|
|
5270
5444
|
const hasPending = !!(context._pendingPropertyDefinitions && Object.keys(context._pendingPropertyDefinitions).length > 0);
|
|
5271
|
-
logger$
|
|
5445
|
+
logger$o(`[writeSuccess guard] hasPending: ${hasPending}, _pendingPropertyDefinitions keys: ${context._pendingPropertyDefinitions ? Object.keys(context._pendingPropertyDefinitions).length : 0}`);
|
|
5272
5446
|
return hasPending;
|
|
5273
5447
|
},
|
|
5274
5448
|
target: 'creatingProperties',
|
|
5275
5449
|
actions: xstate.assign(({ context, event }) => {
|
|
5276
|
-
logger$
|
|
5450
|
+
logger$o(`[writeSuccess] Transitioning to creatingProperties for model "${context.modelName}"`);
|
|
5277
5451
|
// Update _dbId from write output if available (writeToDatabase returns _dbId, not id)
|
|
5278
5452
|
const newContext = { ...context };
|
|
5279
5453
|
const dbId = event.output?._dbId ?? event.output?.id;
|
|
5280
5454
|
if (dbId != null) {
|
|
5281
5455
|
newContext._dbId = dbId;
|
|
5282
|
-
logger$
|
|
5456
|
+
logger$o(`[writeSuccess] Updated _dbId to ${dbId}`);
|
|
5283
5457
|
}
|
|
5284
5458
|
return newContext;
|
|
5285
5459
|
}),
|
|
@@ -5324,12 +5498,12 @@ const modelMachine = xstate.setup({
|
|
|
5324
5498
|
},
|
|
5325
5499
|
creatingProperties: {
|
|
5326
5500
|
entry: ({ context }) => {
|
|
5327
|
-
logger$
|
|
5501
|
+
logger$o(`[creatingProperties entry] Starting property creation for model "${context.modelName}" with ${Object.keys(context._pendingPropertyDefinitions || {}).length} properties`);
|
|
5328
5502
|
},
|
|
5329
5503
|
invoke: {
|
|
5330
5504
|
src: 'createModelProperties',
|
|
5331
5505
|
input: ({ context }) => {
|
|
5332
|
-
logger$
|
|
5506
|
+
logger$o(`[creatingProperties invoke] Invoking createModelProperties with ${Object.keys(context._pendingPropertyDefinitions || {}).length} property definitions`);
|
|
5333
5507
|
return {
|
|
5334
5508
|
context,
|
|
5335
5509
|
propertyDefinitions: context._pendingPropertyDefinitions || {},
|
|
@@ -5359,7 +5533,7 @@ const modelMachine = xstate.setup({
|
|
|
5359
5533
|
createModelPropertiesError: {
|
|
5360
5534
|
target: 'error',
|
|
5361
5535
|
actions: ({ event }) => {
|
|
5362
|
-
logger$
|
|
5536
|
+
logger$o('Error creating model properties:', event.error);
|
|
5363
5537
|
},
|
|
5364
5538
|
},
|
|
5365
5539
|
},
|
|
@@ -5548,6 +5722,10 @@ var PublishMachineStates;
|
|
|
5548
5722
|
PublishMachineStates["PUBLISHING"] = "publishing";
|
|
5549
5723
|
PublishMachineStates["IDLE"] = "idle";
|
|
5550
5724
|
})(PublishMachineStates || (PublishMachineStates = {}));
|
|
5725
|
+
/**
|
|
5726
|
+
* @deprecated Evaluated once at import and ignores `SeedConfig.eas` / publish chain config.
|
|
5727
|
+
* Use `getEasEndpoint()` from `@seedprotocol/eas`.
|
|
5728
|
+
*/
|
|
5551
5729
|
ENV.NEXT_PUBLIC_EAS_ENDPOINT ||
|
|
5552
5730
|
ENV.EAS_ENDPOINT ||
|
|
5553
5731
|
'https://optimism-sepolia.easscan.org/graphql';
|
|
@@ -5845,34 +6023,6 @@ const hydrateNewItem = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
5845
6023
|
});
|
|
5846
6024
|
});
|
|
5847
6025
|
|
|
5848
|
-
/**
|
|
5849
|
-
* Convert Model.properties array to object format (for backward compatibility)
|
|
5850
|
-
* This replaces the old model.schema getter
|
|
5851
|
-
*/
|
|
5852
|
-
function modelPropertiesToObject(properties) {
|
|
5853
|
-
const schemaObj = {};
|
|
5854
|
-
for (const property of properties) {
|
|
5855
|
-
const propContext = property._getSnapshotContext();
|
|
5856
|
-
if (propContext.name) {
|
|
5857
|
-
schemaObj[propContext.name] = {
|
|
5858
|
-
dataType: propContext.dataType,
|
|
5859
|
-
ref: propContext.refModelName || propContext.ref,
|
|
5860
|
-
refValueType: propContext.refValueType,
|
|
5861
|
-
storageType: propContext.storageType,
|
|
5862
|
-
localStorageDir: propContext.localStorageDir,
|
|
5863
|
-
filenameSuffix: propContext.filenameSuffix,
|
|
5864
|
-
required: propContext.required,
|
|
5865
|
-
};
|
|
5866
|
-
}
|
|
5867
|
-
}
|
|
5868
|
-
return schemaObj;
|
|
5869
|
-
}
|
|
5870
|
-
|
|
5871
|
-
var model = /*#__PURE__*/Object.freeze({
|
|
5872
|
-
__proto__: null,
|
|
5873
|
-
modelPropertiesToObject: modelPropertiesToObject
|
|
5874
|
-
});
|
|
5875
|
-
|
|
5876
6026
|
const fetchDataFromEas = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
5877
6027
|
const { ModelClass, modelTableName, versionUid, modelName } = context;
|
|
5878
6028
|
const _initializeAndFetch = async () => {
|
|
@@ -6071,7 +6221,7 @@ function compareMetadataRowsLatestFirst(a, b) {
|
|
|
6071
6221
|
return kb.localId.localeCompare(ka.localId);
|
|
6072
6222
|
}
|
|
6073
6223
|
|
|
6074
|
-
const logger$
|
|
6224
|
+
const logger$n = debug('seedSdk:item:actors:loadOrCreateItem');
|
|
6075
6225
|
/**
|
|
6076
6226
|
* Maps metadata.property_name to the ItemProperty Map key (same rules as the instance loop below).
|
|
6077
6227
|
*/
|
|
@@ -6161,16 +6311,16 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6161
6311
|
const schemaNameToTry = model$1?.schemaName;
|
|
6162
6312
|
if (schemaNameToTry) {
|
|
6163
6313
|
try {
|
|
6164
|
-
const { Schema } = await Promise.resolve().then(function () { return require('./Schema-
|
|
6314
|
+
const { Schema } = await Promise.resolve().then(function () { return require('./Schema-BiJIPLEL.js'); });
|
|
6165
6315
|
const schemaInstance = Schema.create(schemaNameToTry, { waitForReady: false });
|
|
6166
6316
|
const schemaContext = schemaInstance.getService().getSnapshot().context;
|
|
6167
6317
|
if (schemaContext.models?.[modelName]?.properties) {
|
|
6168
6318
|
propertySchemas = schemaContext.models[modelName].properties;
|
|
6169
|
-
logger$
|
|
6319
|
+
logger$n(`Fallback: got ${Object.keys(propertySchemas).length} property schemas from Schema context for ${modelName}`);
|
|
6170
6320
|
}
|
|
6171
6321
|
}
|
|
6172
6322
|
catch (err) {
|
|
6173
|
-
logger$
|
|
6323
|
+
logger$n(`Fallback Schema context failed for ${modelName}: ${err}`);
|
|
6174
6324
|
}
|
|
6175
6325
|
}
|
|
6176
6326
|
if (Object.keys(propertySchemas).length === 0) {
|
|
@@ -6181,13 +6331,13 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6181
6331
|
const models = schemaFile.models;
|
|
6182
6332
|
if (models?.[modelName]?.properties) {
|
|
6183
6333
|
propertySchemas = models[modelName].properties;
|
|
6184
|
-
logger$
|
|
6334
|
+
logger$n(`Fallback: got ${Object.keys(propertySchemas).length} property schemas from loadAllSchemasFromDb for ${modelName}`);
|
|
6185
6335
|
break;
|
|
6186
6336
|
}
|
|
6187
6337
|
}
|
|
6188
6338
|
}
|
|
6189
6339
|
catch (err) {
|
|
6190
|
-
logger$
|
|
6340
|
+
logger$n(`Fallback loadAllSchemasFromDb failed for ${modelName}: ${err}`);
|
|
6191
6341
|
}
|
|
6192
6342
|
}
|
|
6193
6343
|
if (Object.keys(propertySchemas).length === 0) {
|
|
@@ -6200,17 +6350,17 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6200
6350
|
const schemaFile = JSON.parse(content);
|
|
6201
6351
|
if (schemaFile.models?.[modelName]?.properties) {
|
|
6202
6352
|
propertySchemas = schemaFile.models[modelName].properties;
|
|
6203
|
-
logger$
|
|
6353
|
+
logger$n(`Fallback: got ${Object.keys(propertySchemas).length} property schemas from schema file for ${modelName}`);
|
|
6204
6354
|
break;
|
|
6205
6355
|
}
|
|
6206
6356
|
}
|
|
6207
6357
|
}
|
|
6208
6358
|
catch (err) {
|
|
6209
|
-
logger$
|
|
6359
|
+
logger$n(`Fallback schema file scan failed for ${modelName}: ${err}`);
|
|
6210
6360
|
}
|
|
6211
6361
|
}
|
|
6212
6362
|
if (Object.keys(propertySchemas).length === 0) {
|
|
6213
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./index-
|
|
6363
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./index-DPp9rdRL.js'); });
|
|
6214
6364
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
6215
6365
|
const KNOWN_MODEL_FALLBACKS = {
|
|
6216
6366
|
Post: {
|
|
@@ -6222,10 +6372,13 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6222
6372
|
};
|
|
6223
6373
|
if (KNOWN_MODEL_FALLBACKS[modelName]) {
|
|
6224
6374
|
propertySchemas = KNOWN_MODEL_FALLBACKS[modelName];
|
|
6225
|
-
logger$
|
|
6375
|
+
logger$n(`Fallback: using known model schema for ${modelName} (${Object.keys(propertySchemas).length} properties)`);
|
|
6226
6376
|
}
|
|
6227
6377
|
}
|
|
6228
6378
|
}
|
|
6379
|
+
// Fallbacks above may return schema-file shape ({ type, model, items }); normalize to dataType/ref/refValueType.
|
|
6380
|
+
const { normalizePropertyRecordSchema } = await Promise.resolve().then(function () { return require('./property-DlKiAWt4.js'); });
|
|
6381
|
+
propertySchemas = Object.fromEntries(Object.entries(propertySchemas).map(([name, def]) => [name, normalizePropertyRecordSchema(def)]));
|
|
6229
6382
|
// Collapse rows that map to the same instance key (e.g. authorIdentityIds + authors -> authors).
|
|
6230
6383
|
// ItemProperty.create cache does not sync propertyValue on hit; processing order would otherwise
|
|
6231
6384
|
// let an empty "authors" row overwrite a populated storage row.
|
|
@@ -6237,7 +6390,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6237
6390
|
try {
|
|
6238
6391
|
let propertyName = metaRow.propertyName;
|
|
6239
6392
|
if (!propertyName) {
|
|
6240
|
-
logger$
|
|
6393
|
+
logger$n(`Metadata row missing propertyName, skipping`);
|
|
6241
6394
|
continue;
|
|
6242
6395
|
}
|
|
6243
6396
|
const listSchemaKey = resolveStorageNameToSchemaName(propertySchemas, propertyName);
|
|
@@ -6257,7 +6410,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6257
6410
|
// Infer propertyRecordSchema from metadata when schema is missing (enables persistence)
|
|
6258
6411
|
let propSchema = propertySchemas[propertyName];
|
|
6259
6412
|
if (!propSchema && isRefTypeFromMeta) {
|
|
6260
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./index-
|
|
6413
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./index-DPp9rdRL.js'); });
|
|
6261
6414
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
6262
6415
|
propSchema = {
|
|
6263
6416
|
dataType: refSeedType === 'html' ? ModelPropertyDataTypes.Html
|
|
@@ -6285,14 +6438,14 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6285
6438
|
const property = ItemProperty.create(createProps, { waitForReady: false });
|
|
6286
6439
|
if (property) {
|
|
6287
6440
|
propertyInstances.set(propertyName, property);
|
|
6288
|
-
logger$
|
|
6441
|
+
logger$n(`Created/cached ItemProperty instance for propertyName "${propertyName}" with propertyRecordSchema: ${!!createProps.propertyRecordSchema}`);
|
|
6289
6442
|
}
|
|
6290
6443
|
else {
|
|
6291
|
-
logger$
|
|
6444
|
+
logger$n(`ItemProperty.create returned undefined for propertyName "${propertyName}"`);
|
|
6292
6445
|
}
|
|
6293
6446
|
}
|
|
6294
6447
|
catch (error) {
|
|
6295
|
-
logger$
|
|
6448
|
+
logger$n(`Error creating ItemProperty instance for propertyName "${metaRow.propertyName}": ${error}`);
|
|
6296
6449
|
}
|
|
6297
6450
|
}
|
|
6298
6451
|
// Create placeholder ItemProperty instances for model schema properties without metadata
|
|
@@ -6314,17 +6467,17 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6314
6467
|
const property = ItemProperty.create(createProps, { waitForReady: false });
|
|
6315
6468
|
if (property) {
|
|
6316
6469
|
propertyInstances.set(propertyName, property);
|
|
6317
|
-
logger$
|
|
6470
|
+
logger$n(`Created placeholder ItemProperty for model property "${propertyName}" (no metadata)`);
|
|
6318
6471
|
}
|
|
6319
6472
|
}
|
|
6320
6473
|
catch (error) {
|
|
6321
|
-
logger$
|
|
6474
|
+
logger$n(`Error creating placeholder ItemProperty for "${propertyName}": ${error}`);
|
|
6322
6475
|
}
|
|
6323
6476
|
}
|
|
6324
|
-
logger$
|
|
6477
|
+
logger$n(`Finished creating/caching ${propertyInstances.size} ItemProperty instances`);
|
|
6325
6478
|
}
|
|
6326
6479
|
catch (error) {
|
|
6327
|
-
logger$
|
|
6480
|
+
logger$n(`Error in createItemPropertyInstances: ${error}`);
|
|
6328
6481
|
// Don't throw - this is best-effort to pre-populate cache
|
|
6329
6482
|
}
|
|
6330
6483
|
return propertyInstances;
|
|
@@ -6332,7 +6485,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6332
6485
|
const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
6333
6486
|
const _loadOrCreateItem = async () => {
|
|
6334
6487
|
const { seedLocalId, seedUid, modelName } = context;
|
|
6335
|
-
logger$
|
|
6488
|
+
logger$n(`loadOrCreateItem called for modelName: ${modelName}, seedLocalId: ${seedLocalId}, seedUid: ${seedUid}`);
|
|
6336
6489
|
if (!seedLocalId && !seedUid) {
|
|
6337
6490
|
throw new Error('seedLocalId or seedUid is required');
|
|
6338
6491
|
}
|
|
@@ -6362,7 +6515,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
6362
6515
|
.limit(1);
|
|
6363
6516
|
if (seedRecords.length === 0) {
|
|
6364
6517
|
// Seed not found - this is a new item, will be created elsewhere
|
|
6365
|
-
logger$
|
|
6518
|
+
logger$n(`Seed not found in database for seedLocalId: ${seedLocalId}, seedUid: ${seedUid}`);
|
|
6366
6519
|
sendBack({
|
|
6367
6520
|
type: 'loadOrCreateItemSuccess',
|
|
6368
6521
|
item: {
|
|
@@ -6403,7 +6556,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
6403
6556
|
.where(drizzleOrm.eq(seeds.localId, resolvedSeedLocalId))
|
|
6404
6557
|
.limit(1);
|
|
6405
6558
|
if (versionRecords.length === 0) {
|
|
6406
|
-
logger$
|
|
6559
|
+
logger$n(`No version data found for seedLocalId: ${resolvedSeedLocalId}`);
|
|
6407
6560
|
sendBack({
|
|
6408
6561
|
type: 'loadOrCreateItemSuccess',
|
|
6409
6562
|
item: {
|
|
@@ -6427,7 +6580,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
6427
6580
|
const latestVersionLocalId = versionRecord.latestVersionLocalId;
|
|
6428
6581
|
const latestVersionUid = versionRecord.latestVersionUid || undefined;
|
|
6429
6582
|
if (!latestVersionLocalId) {
|
|
6430
|
-
logger$
|
|
6583
|
+
logger$n(`No latest version found for seedLocalId: ${resolvedSeedLocalId}`);
|
|
6431
6584
|
sendBack({
|
|
6432
6585
|
type: 'loadOrCreateItemSuccess',
|
|
6433
6586
|
item: {
|
|
@@ -6458,7 +6611,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
6458
6611
|
.select()
|
|
6459
6612
|
.from(metadataLatest)
|
|
6460
6613
|
.where(drizzleOrm.eq(metadataLatest.rowNum, 1));
|
|
6461
|
-
logger$
|
|
6614
|
+
logger$n(`Found ${metadataRecords.length} latest-per-property metadata rows for seed ${resolvedSeedLocalId} (latestVersionLocalId=${latestVersionLocalId} used for placeholders only)`);
|
|
6462
6615
|
// Step 4: Create ItemProperty instances from metadata records + placeholders for model schema properties
|
|
6463
6616
|
// Always call when we have a valid version so placeholders are created for properties without metadata
|
|
6464
6617
|
const propertyInstances = await createItemPropertyInstances(metadataRecords, resolvedSeedLocalId, resolvedSeedUid, modelName, latestVersionLocalId, latestVersionUid);
|
|
@@ -6490,7 +6643,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
6490
6643
|
});
|
|
6491
6644
|
};
|
|
6492
6645
|
_loadOrCreateItem().catch((error) => {
|
|
6493
|
-
logger$
|
|
6646
|
+
logger$n(`Error in loadOrCreateItem: ${error}`);
|
|
6494
6647
|
sendBack({
|
|
6495
6648
|
type: 'loadOrCreateItemError',
|
|
6496
6649
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -6498,7 +6651,7 @@ const loadOrCreateItem = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
6498
6651
|
});
|
|
6499
6652
|
});
|
|
6500
6653
|
|
|
6501
|
-
const logger$
|
|
6654
|
+
const logger$m = debug('seedSdk:Item:runPublish');
|
|
6502
6655
|
const runPublish = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
6503
6656
|
const { seedLocalId } = context;
|
|
6504
6657
|
const _runPublish = async () => {
|
|
@@ -6514,21 +6667,21 @@ const runPublish = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
|
6514
6667
|
sendBack({ type: 'publishError', error: new Error(`Item not found for seedLocalId: ${seedLocalId}`) });
|
|
6515
6668
|
return;
|
|
6516
6669
|
}
|
|
6517
|
-
const getPublishUploadsMod = await Promise.resolve().then(function () { return require('./getPublishUploads-
|
|
6670
|
+
const getPublishUploadsMod = await Promise.resolve().then(function () { return require('./getPublishUploads-DMhCCKYF.js'); });
|
|
6518
6671
|
const { getPublishUploads } = getPublishUploadsMod;
|
|
6519
|
-
const getPublishPayloadMod = await Promise.resolve().then(function () { return require('./getPublishPayload-
|
|
6672
|
+
const getPublishPayloadMod = await Promise.resolve().then(function () { return require('./getPublishPayload-D5DhLGvN.js'); });
|
|
6520
6673
|
const { getPublishPayload } = getPublishPayloadMod;
|
|
6521
6674
|
const uploads = await getPublishUploads(item);
|
|
6522
6675
|
let uploadedTransactions = [];
|
|
6523
6676
|
const executor = getUploadExecutor();
|
|
6524
6677
|
if (executor && uploads.length > 0) ;
|
|
6525
6678
|
await getPublishPayload(item, uploadedTransactions);
|
|
6526
|
-
logger$
|
|
6679
|
+
logger$m('runPublish: payload prepared (upload/EAS submit stubbed)');
|
|
6527
6680
|
sendBack({ type: 'publishSuccess' });
|
|
6528
6681
|
}
|
|
6529
6682
|
catch (err) {
|
|
6530
6683
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
6531
|
-
logger$
|
|
6684
|
+
logger$m('runPublish error:', error);
|
|
6532
6685
|
sendBack({ type: 'publishError', error });
|
|
6533
6686
|
}
|
|
6534
6687
|
};
|
|
@@ -6887,7 +7040,7 @@ async function getLatestPublishedVersionRow(seedLocalId) {
|
|
|
6887
7040
|
return null;
|
|
6888
7041
|
}
|
|
6889
7042
|
|
|
6890
|
-
const logger$
|
|
7043
|
+
const logger$l = debug('seedSdk:db:read:getItemData');
|
|
6891
7044
|
/**
|
|
6892
7045
|
* Assemble flat ItemData for Item / liveQuery / draft-head authoring.
|
|
6893
7046
|
*
|
|
@@ -6903,7 +7056,7 @@ const getItemData = async ({ modelName, seedLocalId, seedUid, }) => {
|
|
|
6903
7056
|
if (seedUid && !seedLocalId) {
|
|
6904
7057
|
const seedData = await getSeedData({ seedUid });
|
|
6905
7058
|
if (!seedData) {
|
|
6906
|
-
logger$
|
|
7059
|
+
logger$l('[db/queries] [getItem] no seedData seedUid', seedUid);
|
|
6907
7060
|
return;
|
|
6908
7061
|
}
|
|
6909
7062
|
seedLocalId = seedData.localId || undefined;
|
|
@@ -6930,9 +7083,9 @@ const getItemData = async ({ modelName, seedLocalId, seedUid, }) => {
|
|
|
6930
7083
|
.from(seeds)
|
|
6931
7084
|
.where(drizzleOrm.and(...whereClauses))
|
|
6932
7085
|
.limit(1);
|
|
6933
|
-
logger$
|
|
7086
|
+
logger$l('[getItemData] Seed query result', { rowsCount: seedRows?.length || 0, firstRow: seedRows?.[0] });
|
|
6934
7087
|
if (!seedRows || seedRows.length === 0) {
|
|
6935
|
-
logger$
|
|
7088
|
+
logger$l('[db/queries] [getItemDataFromDb] no seedRows found', { modelName, seedLocalId, seedUid });
|
|
6936
7089
|
return;
|
|
6937
7090
|
}
|
|
6938
7091
|
const seedRow = seedRows[0];
|
|
@@ -6954,7 +7107,7 @@ const getItemData = async ({ modelName, seedLocalId, seedUid, }) => {
|
|
|
6954
7107
|
}
|
|
6955
7108
|
}
|
|
6956
7109
|
catch (error) {
|
|
6957
|
-
logger$
|
|
7110
|
+
logger$l('[getItemData] Error deriving schemaName:', error);
|
|
6958
7111
|
}
|
|
6959
7112
|
}
|
|
6960
7113
|
// Now get version data if it exists - query versions table directly
|
|
@@ -7338,12 +7491,12 @@ const resolveRemoteStorage = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
7338
7491
|
});
|
|
7339
7492
|
});
|
|
7340
7493
|
|
|
7341
|
-
const logger$
|
|
7494
|
+
const logger$k = debug('seedSdk:ItemProperty:service:actors:waitForDb');
|
|
7342
7495
|
const waitForDb = xstate.fromCallback(({ sendBack }) => {
|
|
7343
7496
|
// Check immediately first
|
|
7344
7497
|
const appDb = BaseDb.getAppDb();
|
|
7345
7498
|
if (appDb) {
|
|
7346
|
-
logger$
|
|
7499
|
+
logger$k('Database is ready (immediate check)');
|
|
7347
7500
|
sendBack({ type: 'waitForDbSuccess' });
|
|
7348
7501
|
return;
|
|
7349
7502
|
}
|
|
@@ -7355,24 +7508,24 @@ const waitForDb = xstate.fromCallback(({ sendBack }) => {
|
|
|
7355
7508
|
const appDb = BaseDb.getAppDb();
|
|
7356
7509
|
if (appDb) {
|
|
7357
7510
|
clearInterval(interval);
|
|
7358
|
-
logger$
|
|
7511
|
+
logger$k('Database is ready (after polling)');
|
|
7359
7512
|
resolve();
|
|
7360
7513
|
}
|
|
7361
7514
|
else if (Date.now() - startTime > timeout) {
|
|
7362
7515
|
clearInterval(interval);
|
|
7363
7516
|
const error = new Error('Database not available after timeout');
|
|
7364
|
-
logger$
|
|
7517
|
+
logger$k(`Database wait timeout: ${error.message}`);
|
|
7365
7518
|
reject(error);
|
|
7366
7519
|
}
|
|
7367
7520
|
}, 100);
|
|
7368
7521
|
});
|
|
7369
7522
|
_waitForDb
|
|
7370
7523
|
.then(() => {
|
|
7371
|
-
logger$
|
|
7524
|
+
logger$k('Sending waitForDbSuccess event');
|
|
7372
7525
|
sendBack({ type: 'waitForDbSuccess' });
|
|
7373
7526
|
})
|
|
7374
7527
|
.catch((error) => {
|
|
7375
|
-
logger$
|
|
7528
|
+
logger$k(`Error waiting for database: ${error}`);
|
|
7376
7529
|
sendBack({ type: 'waitForDbError', error: error.message });
|
|
7377
7530
|
});
|
|
7378
7531
|
});
|
|
@@ -7466,7 +7619,7 @@ const getRelationValueData = async (propertyValue) => {
|
|
|
7466
7619
|
|
|
7467
7620
|
// Dynamic import to break circular dependency: schema/index -> ... -> resolveRelatedValue -> schema/index
|
|
7468
7621
|
// import { ModelPropertyDataTypes } from '@/schema'
|
|
7469
|
-
const logger$
|
|
7622
|
+
const logger$j = debug('seedSdk:property:actors:resolveRelatedValue');
|
|
7470
7623
|
const storageTransactionIdToContentUrl = new Map();
|
|
7471
7624
|
const refResolvedValueToContentUrl = new Map();
|
|
7472
7625
|
const seedUidToContentUrl = new Map();
|
|
@@ -7474,14 +7627,14 @@ const resolveRelatedValue = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
7474
7627
|
const { isRelation, propertyValue, propertyName, seedUid, propertyRecordSchema, populatedFromDb, schemaUid, } = context;
|
|
7475
7628
|
const _resolveRelatedValue = async () => {
|
|
7476
7629
|
// Use dynamic import to break circular dependency
|
|
7477
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./index-
|
|
7630
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./index-DPp9rdRL.js'); });
|
|
7478
7631
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
7479
7632
|
if (!propertyValue || !isRelation || populatedFromDb) {
|
|
7480
7633
|
return;
|
|
7481
7634
|
}
|
|
7482
7635
|
if (Array.isArray(propertyValue)) {
|
|
7483
7636
|
// TODO: Handle array of seedUids
|
|
7484
|
-
logger$
|
|
7637
|
+
logger$j(`${propertyName} value is an array of seedUids`);
|
|
7485
7638
|
return;
|
|
7486
7639
|
}
|
|
7487
7640
|
if (typeof propertyValue === 'object') {
|
|
@@ -7493,7 +7646,7 @@ const resolveRelatedValue = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
7493
7646
|
parsedValue = JSON.parse(relationKey);
|
|
7494
7647
|
}
|
|
7495
7648
|
catch (error) {
|
|
7496
|
-
logger$
|
|
7649
|
+
logger$j(`${propertyName} value is not a JSON string.`);
|
|
7497
7650
|
}
|
|
7498
7651
|
if (!parsedValue && seedUidToContentUrl.has(relationKey)) {
|
|
7499
7652
|
const contentUrl = seedUidToContentUrl.get(relationKey);
|
|
@@ -7508,7 +7661,7 @@ const resolveRelatedValue = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
7508
7661
|
return true;
|
|
7509
7662
|
}
|
|
7510
7663
|
if (Array.isArray(parsedValue)) {
|
|
7511
|
-
logger$
|
|
7664
|
+
logger$j(`${propertyName} value is a stringified array of seedUids`);
|
|
7512
7665
|
return;
|
|
7513
7666
|
}
|
|
7514
7667
|
const storageTransactionId = await getStorageTransactionIdForSeedUid(relationKey);
|
|
@@ -7548,7 +7701,7 @@ const resolveRelatedValue = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
7548
7701
|
// This handles a local-only relation value and resolves from the filesystem
|
|
7549
7702
|
if (refResolvedValue &&
|
|
7550
7703
|
propertyRecordSchema &&
|
|
7551
|
-
propertyRecordSchema.dataType
|
|
7704
|
+
isDataType(propertyRecordSchema.dataType, ModelPropertyDataTypes.Relation) &&
|
|
7552
7705
|
propertyValueFromDb &&
|
|
7553
7706
|
typeof propertyValueFromDb === 'string' &&
|
|
7554
7707
|
propertyValueFromDb.length === 10 &&
|
|
@@ -7851,48 +8004,15 @@ function extractArweaveTransactionId(raw) {
|
|
|
7851
8004
|
return t;
|
|
7852
8005
|
}
|
|
7853
8006
|
/**
|
|
7854
|
-
* GET /raw/{txId} on each
|
|
7855
|
-
* arweave.
|
|
8007
|
+
* GET /raw/{txId} on each read gateway, preferred ones ({@link setPreferredArweaveReadBaseUrls})
|
|
8008
|
+
* first. Avoids arweave.js /tx/.../offset which often 404s on arweave.net while another gateway
|
|
8009
|
+
* (e.g. ar.seedprotocol.io, or the one the item was just uploaded through) still serves the data.
|
|
7856
8010
|
*/
|
|
7857
8011
|
async function fetchHtmlViaRawAcrossGateways(txId) {
|
|
7858
8012
|
const id = extractArweaveTransactionId(txId);
|
|
7859
8013
|
if (!id || SEED_UID_HEX_RE.test(id))
|
|
7860
8014
|
return undefined;
|
|
7861
|
-
|
|
7862
|
-
const resolved = arweave.getResolvedSeedGatewayEndpoints();
|
|
7863
|
-
if (!resolved || (resolved.activePath !== 'hyper-sidecar' && resolved.activePath !== 'http-proxy')) {
|
|
7864
|
-
const { ensureReadGatewaySelected } = await import('@seedprotocol/arweave');
|
|
7865
|
-
await ensureReadGatewaySelected().catch(() => { });
|
|
7866
|
-
}
|
|
7867
|
-
}
|
|
7868
|
-
catch {
|
|
7869
|
-
/* optional */
|
|
7870
|
-
}
|
|
7871
|
-
const { BaseArweaveClient } = await import('@seedprotocol/arweave');
|
|
7872
|
-
const protocol = BaseArweaveClient.getProtocol();
|
|
7873
|
-
const resolved = arweave.getResolvedSeedGatewayEndpoints();
|
|
7874
|
-
const hosts = resolved
|
|
7875
|
-
? arweave.getReadGatewayHostsForConfig(resolved, arweave.getDefaultArweaveReadGatewayHostsOrdered())
|
|
7876
|
-
: arweave.getArweaveReadGatewayHostsForPrimary(BaseArweaveClient.getHost());
|
|
7877
|
-
for (const host of hosts) {
|
|
7878
|
-
const h = host.trim().replace(/\/$/, '');
|
|
7879
|
-
if (!h)
|
|
7880
|
-
continue;
|
|
7881
|
-
const url = `${protocol}://${h}/raw/${encodeURIComponent(id)}`;
|
|
7882
|
-
try {
|
|
7883
|
-
const res = await fetch(url, { method: 'GET', credentials: 'omit' });
|
|
7884
|
-
if (!res.ok)
|
|
7885
|
-
continue;
|
|
7886
|
-
const text = await res.text();
|
|
7887
|
-
if (typeof text === 'string' && text.length > 0) {
|
|
7888
|
-
return text;
|
|
7889
|
-
}
|
|
7890
|
-
}
|
|
7891
|
-
catch {
|
|
7892
|
-
/* next gateway */
|
|
7893
|
-
}
|
|
7894
|
-
}
|
|
7895
|
-
return undefined;
|
|
8015
|
+
return arweave.fetchArweaveRawTextAcrossGateways(id);
|
|
7896
8016
|
}
|
|
7897
8017
|
/**
|
|
7898
8018
|
* Resolve the Html storage seed's `local_id` used for the `{localId}.html` file name.
|
|
@@ -7990,7 +8110,7 @@ async function readHtmlBodyForStorageSeedPropertyValue(propertyValue) {
|
|
|
7990
8110
|
|
|
7991
8111
|
// Dynamic import to break circular dependency: schema/index -> ... -> hydrateFromDb -> schema/index
|
|
7992
8112
|
// import { ModelPropertyDataTypes } from '@/schema'
|
|
7993
|
-
const logger$
|
|
8113
|
+
const logger$i = debug('seedSdk:property:actors:hydrateFromDb');
|
|
7994
8114
|
const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
7995
8115
|
const { seedUid, seedLocalId, propertyName: propertyNameRaw, propertyRecordSchema, modelName, } = context;
|
|
7996
8116
|
if (!propertyNameRaw) {
|
|
@@ -8001,7 +8121,7 @@ const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
8001
8121
|
// to use dynamically imported ModelPropertyDataTypes
|
|
8002
8122
|
const _hydrateFromDb = async () => {
|
|
8003
8123
|
// Use dynamic import to break circular dependency
|
|
8004
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./index-
|
|
8124
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./index-DPp9rdRL.js'); });
|
|
8005
8125
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
8006
8126
|
const appDb = BaseDb.getAppDb();
|
|
8007
8127
|
const whereClauses = [];
|
|
@@ -8107,7 +8227,7 @@ const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
8107
8227
|
}
|
|
8108
8228
|
}
|
|
8109
8229
|
catch (e) {
|
|
8110
|
-
logger$
|
|
8230
|
+
logger$i('[hydrateFromDb] Image file resolution error', e);
|
|
8111
8231
|
}
|
|
8112
8232
|
}
|
|
8113
8233
|
}
|
|
@@ -8138,7 +8258,7 @@ const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
8138
8258
|
}
|
|
8139
8259
|
}
|
|
8140
8260
|
catch (e) {
|
|
8141
|
-
logger$
|
|
8261
|
+
logger$i('[hydrateFromDb] File resolution error', e);
|
|
8142
8262
|
}
|
|
8143
8263
|
}
|
|
8144
8264
|
if (propertyRecordSchema &&
|
|
@@ -8241,11 +8361,11 @@ const hydrateFromDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
8241
8361
|
});
|
|
8242
8362
|
});
|
|
8243
8363
|
|
|
8244
|
-
const logger$
|
|
8364
|
+
const logger$h = debug('seedSdk:itemProperty:actors:loadOrCreateProperty');
|
|
8245
8365
|
const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
8246
8366
|
const _loadOrCreateProperty = async () => {
|
|
8247
8367
|
const { seedLocalId, seedUid, propertyName, versionLocalId } = context;
|
|
8248
|
-
logger$
|
|
8368
|
+
logger$h(`loadOrCreateProperty called for propertyName: ${propertyName}, seedLocalId: ${seedLocalId}, seedUid: ${seedUid}`);
|
|
8249
8369
|
if (!seedLocalId && !seedUid) {
|
|
8250
8370
|
throw new Error('seedLocalId or seedUid is required');
|
|
8251
8371
|
}
|
|
@@ -8291,15 +8411,15 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
8291
8411
|
const schemas = modelPropertiesToObject(model$1.properties);
|
|
8292
8412
|
propertyRecordSchema = schemas[propertyName];
|
|
8293
8413
|
if (propertyRecordSchema) {
|
|
8294
|
-
logger$
|
|
8414
|
+
logger$h(`Metadata not found: loaded propertyRecordSchema from Model for propertyName "${propertyName}"`);
|
|
8295
8415
|
}
|
|
8296
8416
|
}
|
|
8297
8417
|
}
|
|
8298
8418
|
catch (error) {
|
|
8299
|
-
logger$
|
|
8419
|
+
logger$h(`Metadata not found: Model fallback failed for propertyName "${propertyName}": ${error}`);
|
|
8300
8420
|
}
|
|
8301
8421
|
}
|
|
8302
|
-
logger$
|
|
8422
|
+
logger$h(`Metadata not found in database for propertyName: ${propertyName}, seedLocalId: ${seedLocalId}`);
|
|
8303
8423
|
sendBack({
|
|
8304
8424
|
type: 'loadOrCreatePropertySuccess',
|
|
8305
8425
|
property: {
|
|
@@ -8365,7 +8485,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
8365
8485
|
};
|
|
8366
8486
|
// Merge with schema from file/DB to get validation rules (enum, pattern, etc.) - properties table doesn't store these
|
|
8367
8487
|
try {
|
|
8368
|
-
const { getPropertySchema } = await Promise.resolve().then(function () { return require('./property-
|
|
8488
|
+
const { getPropertySchema } = await Promise.resolve().then(function () { return require('./property-DlKiAWt4.js'); });
|
|
8369
8489
|
let schemaFromFile = await getPropertySchema(normalizedModelName, propertyName);
|
|
8370
8490
|
if (!schemaFromFile?.validation) {
|
|
8371
8491
|
// Fallback: get validation from schemaData in database (Schema context may not be loaded yet)
|
|
@@ -8403,7 +8523,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
8403
8523
|
}
|
|
8404
8524
|
}
|
|
8405
8525
|
catch (error) {
|
|
8406
|
-
logger$
|
|
8526
|
+
logger$h(`Error loading propertyRecordSchema from database: ${error}`);
|
|
8407
8527
|
// Continue without propertyRecordSchema
|
|
8408
8528
|
}
|
|
8409
8529
|
}
|
|
@@ -8421,12 +8541,12 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
8421
8541
|
const schemas = modelPropertiesToObject(model$1.properties);
|
|
8422
8542
|
propertyRecordSchema = schemas[propertyName];
|
|
8423
8543
|
if (propertyRecordSchema) {
|
|
8424
|
-
logger$
|
|
8544
|
+
logger$h(`Fallback: loaded propertyRecordSchema from Model for propertyName "${propertyName}"`);
|
|
8425
8545
|
}
|
|
8426
8546
|
}
|
|
8427
8547
|
}
|
|
8428
8548
|
catch (error) {
|
|
8429
|
-
logger$
|
|
8549
|
+
logger$h(`Fallback Model lookup failed for propertyName "${propertyName}": ${error}`);
|
|
8430
8550
|
}
|
|
8431
8551
|
}
|
|
8432
8552
|
// For Html: read file content for renderValue (propertyValue is seed ID; blob URLs in DB are invalid after reload)
|
|
@@ -8467,7 +8587,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
8467
8587
|
}
|
|
8468
8588
|
}
|
|
8469
8589
|
catch (e) {
|
|
8470
|
-
logger$
|
|
8590
|
+
logger$h(`Failed to read Html file for ${propertyName}: ${e}`);
|
|
8471
8591
|
}
|
|
8472
8592
|
}
|
|
8473
8593
|
// Covers missing ref row, wrong ref, or DB dataType casing "html" (handled by isHtml above).
|
|
@@ -8525,7 +8645,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
8525
8645
|
});
|
|
8526
8646
|
}
|
|
8527
8647
|
catch (e) {
|
|
8528
|
-
logger$
|
|
8648
|
+
logger$h(`loadOrCreateProperty: updateMetadata refResolvedValue failed for ${propertyName}:`, e);
|
|
8529
8649
|
}
|
|
8530
8650
|
}
|
|
8531
8651
|
}
|
|
@@ -8547,7 +8667,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
8547
8667
|
}
|
|
8548
8668
|
}
|
|
8549
8669
|
catch (e) {
|
|
8550
|
-
logger$
|
|
8670
|
+
logger$h(`Failed to resolve Image file for ${propertyName}: ${e}`);
|
|
8551
8671
|
}
|
|
8552
8672
|
}
|
|
8553
8673
|
const isFile = refSeedType === 'file' ||
|
|
@@ -8565,7 +8685,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
8565
8685
|
}
|
|
8566
8686
|
}
|
|
8567
8687
|
catch (e) {
|
|
8568
|
-
logger$
|
|
8688
|
+
logger$h(`Failed to resolve File for ${propertyName}: ${e}`);
|
|
8569
8689
|
}
|
|
8570
8690
|
}
|
|
8571
8691
|
let propertyValueOut = metadataRecord.propertyValue || undefined;
|
|
@@ -8597,7 +8717,7 @@ const loadOrCreateProperty = xstate.fromCallback(({ sendBack, input: { context }
|
|
|
8597
8717
|
});
|
|
8598
8718
|
};
|
|
8599
8719
|
_loadOrCreateProperty().catch((error) => {
|
|
8600
|
-
logger$
|
|
8720
|
+
logger$h(`Error in loadOrCreateProperty: ${error}`);
|
|
8601
8721
|
sendBack({
|
|
8602
8722
|
type: 'loadOrCreatePropertyError',
|
|
8603
8723
|
error: error instanceof Error ? error.message : String(error),
|
|
@@ -8627,10 +8747,10 @@ const getVersionData = async ({ localId, seedLocalId, uid, }) => {
|
|
|
8627
8747
|
return queryRows[0];
|
|
8628
8748
|
};
|
|
8629
8749
|
|
|
8630
|
-
const logger$
|
|
8750
|
+
const logger$g = debug('seedSdk:write:updateItemPropertyValue');
|
|
8631
8751
|
const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, newValue, seedUid, seedLocalId, modelName, refSeedType, refResolvedValue, refResolvedDisplayValue, versionLocalId, versionUid, schemaUid, localStorageDir, dataType, refValueType, }) => {
|
|
8632
8752
|
if (!localIdParam && !seedLocalId) {
|
|
8633
|
-
logger$
|
|
8753
|
+
logger$g(`[db/write] [updateItemPropertyValue] no propertyLocalId or seedLocalId for property: ${propertyName}`);
|
|
8634
8754
|
return;
|
|
8635
8755
|
}
|
|
8636
8756
|
let safeNewValue = newValue;
|
|
@@ -8703,7 +8823,7 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
|
|
|
8703
8823
|
modelType === modelName?.toLowerCase() &&
|
|
8704
8824
|
refSeedTypeFromDb === refSeedType &&
|
|
8705
8825
|
refResolvedValueFromDb === refResolvedValue) {
|
|
8706
|
-
logger$
|
|
8826
|
+
logger$g(`[db/write] [updateItemPropertyValue] value is the same as most recent record for property: ${propertyNameFromDb}`);
|
|
8707
8827
|
return;
|
|
8708
8828
|
}
|
|
8709
8829
|
// This means we already have a local-only record so we should just update that one
|
|
@@ -8831,9 +8951,9 @@ const analyzeInput = xstate.fromCallback(({ sendBack, input: { context, event }
|
|
|
8831
8951
|
}
|
|
8832
8952
|
const _analyzeInput = async () => {
|
|
8833
8953
|
// Use dynamic import to break circular dependency
|
|
8834
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./index-
|
|
8954
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./index-DPp9rdRL.js'); });
|
|
8835
8955
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
8836
|
-
const { SchemaValidationService } = await Promise.resolve().then(function () { return require('./SchemaValidationService-
|
|
8956
|
+
const { SchemaValidationService } = await Promise.resolve().then(function () { return require('./SchemaValidationService-DtYs_CNY.js'); });
|
|
8837
8957
|
let propertyName = propertyNameRaw;
|
|
8838
8958
|
if (!propertyName) {
|
|
8839
8959
|
throw new Error('propertyName is required');
|
|
@@ -9008,6 +9128,12 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
|
|
|
9008
9128
|
if (!metadataValues.modelType && metadataValues.modelName) {
|
|
9009
9129
|
metadataValues.modelType = casing.toSnakeCase(metadataValues.modelName);
|
|
9010
9130
|
}
|
|
9131
|
+
// List of Relation rows live under the storage name (authors → authorIdentityIds), never the schema key.
|
|
9132
|
+
if (metadataValues.propertyName) {
|
|
9133
|
+
const storageName = listRelationEasPropertyName(metadataValues.propertyName, propertyRecordSchema);
|
|
9134
|
+
if (storageName)
|
|
9135
|
+
metadataValues.propertyName = storageName;
|
|
9136
|
+
}
|
|
9011
9137
|
const isItemStorage = propertyRecordSchema && propertyRecordSchema.storageType === 'ItemStorage';
|
|
9012
9138
|
// if (
|
|
9013
9139
|
// propertyRecordSchema &&
|
|
@@ -9022,7 +9148,11 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
|
|
|
9022
9148
|
// }
|
|
9023
9149
|
// Convert propertyValue to string if it's not already (metadata table expects text)
|
|
9024
9150
|
if (metadataValues.propertyValue !== undefined && metadataValues.propertyValue !== null) {
|
|
9025
|
-
if (
|
|
9151
|
+
if (Array.isArray(metadataValues.propertyValue)) {
|
|
9152
|
+
// List values: JSON array is the storage format (String() would give legacy comma-separated ids)
|
|
9153
|
+
metadataValues.propertyValue = JSON.stringify(metadataValues.propertyValue);
|
|
9154
|
+
}
|
|
9155
|
+
else if (typeof metadataValues.propertyValue !== 'string') {
|
|
9026
9156
|
metadataValues.propertyValue = String(metadataValues.propertyValue);
|
|
9027
9157
|
}
|
|
9028
9158
|
}
|
|
@@ -9031,7 +9161,7 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
|
|
|
9031
9161
|
propertyRecordSchema?.validation &&
|
|
9032
9162
|
metadataValues.propertyValue != null &&
|
|
9033
9163
|
metadataValues.propertyValue !== '') {
|
|
9034
|
-
const { SchemaValidationService } = await Promise.resolve().then(function () { return require('./SchemaValidationService-
|
|
9164
|
+
const { SchemaValidationService } = await Promise.resolve().then(function () { return require('./SchemaValidationService-DtYs_CNY.js'); });
|
|
9035
9165
|
const validationService = new SchemaValidationService();
|
|
9036
9166
|
const validationResult = validationService.validatePropertyValue(metadataValues.propertyValue, normalizeDataType(propertyRecordSchema.dataType), propertyRecordSchema.validation, propertyRecordSchema.refValueType
|
|
9037
9167
|
? normalizeDataType(String(propertyRecordSchema.refValueType))
|
|
@@ -9082,29 +9212,44 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
|
|
|
9082
9212
|
}
|
|
9083
9213
|
}
|
|
9084
9214
|
}
|
|
9085
|
-
// Resolve property_id for FK: prefer explicit value, then propertyRecordSchema.id, else lookup
|
|
9215
|
+
// Resolve property_id for FK: prefer explicit value, then propertyRecordSchema.id, else lookup.
|
|
9216
|
+
// propertyRecordSchema.id is the integer properties.id only when built from a DB row; from schema
|
|
9217
|
+
// files and Model it is the schemaFileId string, which must be looked up (Number() gives NaN).
|
|
9086
9218
|
if (metadataValues.propertyId == null) {
|
|
9087
|
-
|
|
9088
|
-
|
|
9089
|
-
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
|
|
9103
|
-
|
|
9104
|
-
|
|
9105
|
-
|
|
9106
|
-
|
|
9107
|
-
|
|
9219
|
+
const schemaId = propertyRecordSchema?.id;
|
|
9220
|
+
const modelKey = metadataValues.modelName ?? metadataValues.modelType ?? undefined;
|
|
9221
|
+
if (typeof schemaId === 'number' && Number.isInteger(schemaId)) {
|
|
9222
|
+
metadataValues.propertyId = schemaId;
|
|
9223
|
+
}
|
|
9224
|
+
else if (modelKey) {
|
|
9225
|
+
if (typeof schemaId === 'string' && schemaId) {
|
|
9226
|
+
metadataValues.propertyId =
|
|
9227
|
+
(await getPropertyIdForSchemaFileId(modelKey, schemaId)) ?? undefined;
|
|
9228
|
+
}
|
|
9229
|
+
if (metadataValues.propertyId == null && metadataValues.propertyName) {
|
|
9230
|
+
metadataValues.propertyId =
|
|
9231
|
+
(await getPropertyIdForModelAndName(modelKey, metadataValues.propertyName)) ?? undefined;
|
|
9232
|
+
}
|
|
9233
|
+
}
|
|
9234
|
+
}
|
|
9235
|
+
let inserted;
|
|
9236
|
+
try {
|
|
9237
|
+
inserted = await appDb
|
|
9238
|
+
.insert(metadata$1)
|
|
9239
|
+
.values({
|
|
9240
|
+
...metadataValues,
|
|
9241
|
+
createdAt: Date.now(),
|
|
9242
|
+
updatedAt: Date.now(),
|
|
9243
|
+
})
|
|
9244
|
+
.returning();
|
|
9245
|
+
}
|
|
9246
|
+
catch (error) {
|
|
9247
|
+
// Drizzle's message is the full SQL; the driver error that explains it is only on `cause`.
|
|
9248
|
+
const cause = error?.cause;
|
|
9249
|
+
const reason = cause instanceof Error ? cause.message : cause != null ? String(cause) : undefined;
|
|
9250
|
+
throw new Error(`Failed to insert metadata for property ${metadataValues.propertyName}` +
|
|
9251
|
+
(reason ? `: ${reason}` : `: ${error instanceof Error ? error.message : String(error)}`), { cause: error });
|
|
9252
|
+
}
|
|
9108
9253
|
if (!inserted || inserted.length === 0) {
|
|
9109
9254
|
throw new Error(`Failed to insert metadata record for property ${metadataValues.propertyName}`);
|
|
9110
9255
|
}
|
|
@@ -9624,7 +9769,7 @@ const saveRelation = xstate.fromCallback(({ sendBack, input: { context, event }
|
|
|
9624
9769
|
}
|
|
9625
9770
|
const _saveRelation = async () => {
|
|
9626
9771
|
// Use dynamic import to break circular dependency
|
|
9627
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./index-
|
|
9772
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./index-DPp9rdRL.js'); });
|
|
9628
9773
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
9629
9774
|
if (!propertyNameRaw) {
|
|
9630
9775
|
throw new Error('propertyName is required');
|
|
@@ -9637,7 +9782,7 @@ const saveRelation = xstate.fromCallback(({ sendBack, input: { context, event }
|
|
|
9637
9782
|
if (newValue instanceof File) {
|
|
9638
9783
|
newValueType = 'file';
|
|
9639
9784
|
}
|
|
9640
|
-
if (propertyRecordSchema.dataType
|
|
9785
|
+
if (isDataType(propertyRecordSchema.dataType, ModelPropertyDataTypes.Image)) {
|
|
9641
9786
|
sendBack({
|
|
9642
9787
|
type: 'saveImage',
|
|
9643
9788
|
newValue,
|
|
@@ -9827,7 +9972,19 @@ const saveItemStorage = xstate.fromCallback(({ sendBack, input: { context, event
|
|
|
9827
9972
|
});
|
|
9828
9973
|
});
|
|
9829
9974
|
|
|
9830
|
-
|
|
9975
|
+
/**
|
|
9976
|
+
* A List-of-relation schema can arrive after construction (item loaded before its model).
|
|
9977
|
+
* Move the context to the storage name (staff → staffIdentityIds) so saves and publish use one name;
|
|
9978
|
+
* ItemProperty keeps exposing the schema key.
|
|
9979
|
+
*/
|
|
9980
|
+
const withListRelationStorageName = (context) => {
|
|
9981
|
+
if (!context.propertyName || !context.propertyRecordSchema)
|
|
9982
|
+
return context;
|
|
9983
|
+
const storageName = listRelationEasPropertyName(context.propertyName, normalizePropertyRecordSchema(context.propertyRecordSchema));
|
|
9984
|
+
if (!storageName || storageName === context.propertyName)
|
|
9985
|
+
return context;
|
|
9986
|
+
return { ...context, propertyName: storageName, isRelation: true };
|
|
9987
|
+
};
|
|
9831
9988
|
const propertyMachine = xstate.setup({
|
|
9832
9989
|
types: {
|
|
9833
9990
|
context: {},
|
|
@@ -9868,6 +10025,7 @@ const propertyMachine = xstate.setup({
|
|
|
9868
10025
|
actions: xstate.assign({
|
|
9869
10026
|
isSaving: true,
|
|
9870
10027
|
_saveError: undefined,
|
|
10028
|
+
_saveValidationErrors: undefined,
|
|
9871
10029
|
}),
|
|
9872
10030
|
target: '.saving',
|
|
9873
10031
|
},
|
|
@@ -9881,7 +10039,9 @@ const propertyMachine = xstate.setup({
|
|
|
9881
10039
|
}
|
|
9882
10040
|
newContext[key] = event[key];
|
|
9883
10041
|
}
|
|
9884
|
-
return
|
|
10042
|
+
return 'propertyRecordSchema' in event
|
|
10043
|
+
? withListRelationStorageName(newContext)
|
|
10044
|
+
: newContext;
|
|
9885
10045
|
}),
|
|
9886
10046
|
},
|
|
9887
10047
|
destroyStarted: {
|
|
@@ -9940,7 +10100,7 @@ const propertyMachine = xstate.setup({
|
|
|
9940
10100
|
target: 'idle',
|
|
9941
10101
|
actions: xstate.assign(({ context, event }) => {
|
|
9942
10102
|
const property = event.property;
|
|
9943
|
-
return {
|
|
10103
|
+
return withListRelationStorageName({
|
|
9944
10104
|
...context,
|
|
9945
10105
|
propertyName: property.propertyName || context.propertyName,
|
|
9946
10106
|
propertyValue: property.propertyValue !== undefined ? property.propertyValue : context.propertyValue,
|
|
@@ -9958,7 +10118,7 @@ const propertyMachine = xstate.setup({
|
|
|
9958
10118
|
refResolvedValue: property.refResolvedValue !== undefined ? property.refResolvedValue : context.refResolvedValue,
|
|
9959
10119
|
refResolvedDisplayValue: property.refResolvedDisplayValue !== undefined ? property.refResolvedDisplayValue : context.refResolvedDisplayValue,
|
|
9960
10120
|
localStorageDir: property.localStorageDir !== undefined ? property.localStorageDir : context.localStorageDir,
|
|
9961
|
-
};
|
|
10121
|
+
});
|
|
9962
10122
|
}),
|
|
9963
10123
|
},
|
|
9964
10124
|
loadOrCreatePropertyError: {
|
|
@@ -10445,7 +10605,8 @@ const resolvePropertyRecordSchemaFromModel = async (modelName, propertyName, mod
|
|
|
10445
10605
|
// Fallback: resolve from schema JSON when Model not in cache/DB (e.g. PermaPress sync failed but schema in DB)
|
|
10446
10606
|
const schemaProp = await resolvePropertyRecordSchemaFromSchemaData(modelName, propertyName, modelType);
|
|
10447
10607
|
if (schemaProp) {
|
|
10448
|
-
|
|
10608
|
+
// Schema JSON uses file shape ({ type: 'Html' }); callers read dataType.
|
|
10609
|
+
return normalizePropertyRecordSchema(schemaProp);
|
|
10449
10610
|
}
|
|
10450
10611
|
return undefined;
|
|
10451
10612
|
}
|
|
@@ -10465,7 +10626,7 @@ const resolvePropertyRecordSchemaFromModel = async (modelName, propertyName, mod
|
|
|
10465
10626
|
};
|
|
10466
10627
|
/** Convert modelType (snake_case from DB) to Model name (PascalCase). startCase adds spaces ("Test Post"); Model names are "TestPost". */
|
|
10467
10628
|
const modelTypeToModelName = (modelType) => modelType ? lodashEs.upperFirst(lodashEs.camelCase(modelType)) : '';
|
|
10468
|
-
const logger$
|
|
10629
|
+
const logger$f = debug('seedSdk:property:class');
|
|
10469
10630
|
// Define tracked properties for the Proxy
|
|
10470
10631
|
// These properties will be read from/written to the actor context
|
|
10471
10632
|
const TRACKED_PROPERTIES$2 = [
|
|
@@ -10486,18 +10647,29 @@ const TRACKED_PROPERTIES$2 = [
|
|
|
10486
10647
|
// WeakMap to store mutable state per ItemProperty instance
|
|
10487
10648
|
// This avoids issues with read-only properties when instances are frozen by Immer
|
|
10488
10649
|
const itemPropertyInstanceState = new WeakMap();
|
|
10650
|
+
/** Thrown by ItemProperty.save() when the value failed validation (enum, pattern, minLength, maxLength). */
|
|
10651
|
+
class ItemPropertySaveValidationError extends Error {
|
|
10652
|
+
constructor(message, validationErrors) {
|
|
10653
|
+
super(message);
|
|
10654
|
+
this.validationErrors = validationErrors;
|
|
10655
|
+
this.name = 'ItemPropertySaveValidationError';
|
|
10656
|
+
}
|
|
10657
|
+
}
|
|
10489
10658
|
class ItemProperty {
|
|
10490
10659
|
constructor(initialValues) {
|
|
10491
10660
|
this._isRelation = false;
|
|
10492
10661
|
this._isList = false;
|
|
10493
10662
|
this.find = ItemProperty.find;
|
|
10494
10663
|
const { modelName, propertyName, propertyValue, seedLocalId, seedUid, versionLocalId, versionUid, storageTransactionId, schemaUid, refResolvedValue, refResolvedDisplayValue, localStorageDir, refSeedType } = initialValues;
|
|
10664
|
+
// Fallback schema sources can hand us schema-file shape ({ type: 'html' }); everything below reads dataType.
|
|
10665
|
+
const propertyRecordSchema = normalizePropertyRecordSchema(initialValues.propertyRecordSchema);
|
|
10495
10666
|
if (!modelName) {
|
|
10496
10667
|
throw new Error('Model name is required');
|
|
10497
10668
|
}
|
|
10498
10669
|
if (!propertyName) {
|
|
10499
10670
|
throw new Error(`Property name not provided`);
|
|
10500
10671
|
}
|
|
10672
|
+
this._constructedPropertyName = propertyName;
|
|
10501
10673
|
// ItemProperty no longer depends on Model - property schema will be loaded from database
|
|
10502
10674
|
// via loadOrCreateProperty actor or can be provided in initialValues
|
|
10503
10675
|
const serviceInput = {
|
|
@@ -10511,7 +10683,7 @@ class ItemProperty {
|
|
|
10511
10683
|
storageTransactionId,
|
|
10512
10684
|
// propertyRecordSchema will be loaded from database via loadOrCreateProperty actor
|
|
10513
10685
|
// or can be provided in initialValues if available
|
|
10514
|
-
propertyRecordSchema
|
|
10686
|
+
propertyRecordSchema,
|
|
10515
10687
|
schemaUid,
|
|
10516
10688
|
isSaving: false,
|
|
10517
10689
|
isRelation: false,
|
|
@@ -10523,16 +10695,13 @@ class ItemProperty {
|
|
|
10523
10695
|
};
|
|
10524
10696
|
// Property schema will be loaded from database via loadOrCreateProperty actor
|
|
10525
10697
|
// For now, use propertyRecordSchema from initialValues if provided
|
|
10526
|
-
const propertyRecordSchema = initialValues.propertyRecordSchema;
|
|
10527
10698
|
if (propertyRecordSchema) {
|
|
10528
|
-
this._dataType = propertyRecordSchema.dataType;
|
|
10699
|
+
this._dataType = normalizeDataType(propertyRecordSchema.dataType);
|
|
10529
10700
|
serviceInput.propertyRecordSchema = propertyRecordSchema;
|
|
10530
|
-
|
|
10531
|
-
// ModelPropertyDataTypes values are stable string constants
|
|
10532
|
-
if (propertyRecordSchema.dataType === 'Relation') {
|
|
10701
|
+
if (isDataType(propertyRecordSchema.dataType, exports.ModelPropertyDataTypes.Relation)) {
|
|
10533
10702
|
this._isRelation = true;
|
|
10534
10703
|
}
|
|
10535
|
-
if (propertyRecordSchema.dataType
|
|
10704
|
+
if (isDataType(propertyRecordSchema.dataType, exports.ModelPropertyDataTypes.List)) {
|
|
10536
10705
|
this._isList = true;
|
|
10537
10706
|
const listRef = propertyRecordSchema.ref ||
|
|
10538
10707
|
propertyRecordSchema.refModelName;
|
|
@@ -10547,7 +10716,7 @@ class ItemProperty {
|
|
|
10547
10716
|
serviceInput.propertyValue = JSON.parse(propertyValue);
|
|
10548
10717
|
}
|
|
10549
10718
|
catch (e) {
|
|
10550
|
-
logger$
|
|
10719
|
+
logger$f('List property value is not JSON', e);
|
|
10551
10720
|
}
|
|
10552
10721
|
}
|
|
10553
10722
|
}
|
|
@@ -10570,7 +10739,7 @@ class ItemProperty {
|
|
|
10570
10739
|
return;
|
|
10571
10740
|
}
|
|
10572
10741
|
// Use dynamic import to break circular dependency
|
|
10573
|
-
const schemaMod = await Promise.resolve().then(function () { return require('./index-
|
|
10742
|
+
const schemaMod = await Promise.resolve().then(function () { return require('./index-DPp9rdRL.js'); });
|
|
10574
10743
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
10575
10744
|
const { context } = snapshot;
|
|
10576
10745
|
const { propertyRecordSchema } = context;
|
|
@@ -10585,9 +10754,9 @@ class ItemProperty {
|
|
|
10585
10754
|
}
|
|
10586
10755
|
let renderValue;
|
|
10587
10756
|
const isImage = propertyRecordSchema &&
|
|
10588
|
-
propertyRecordSchema.dataType
|
|
10757
|
+
isDataType(propertyRecordSchema.dataType, ModelPropertyDataTypes.Image);
|
|
10589
10758
|
const isFile = propertyRecordSchema &&
|
|
10590
|
-
propertyRecordSchema.dataType
|
|
10759
|
+
isDataType(propertyRecordSchema.dataType, ModelPropertyDataTypes.File);
|
|
10591
10760
|
const isItemStorage = propertyRecordSchema &&
|
|
10592
10761
|
propertyRecordSchema.storageType &&
|
|
10593
10762
|
propertyRecordSchema.storageType === 'ItemStorage' &&
|
|
@@ -10664,7 +10833,7 @@ class ItemProperty {
|
|
|
10664
10833
|
}
|
|
10665
10834
|
}
|
|
10666
10835
|
catch (e) {
|
|
10667
|
-
logger$
|
|
10836
|
+
logger$f(`[ItemProperty] [${context.seedLocalId}] [${context.propertyName}] [storageType] error`, e);
|
|
10668
10837
|
renderValue = isHtml ? undefined : 'No file found';
|
|
10669
10838
|
}
|
|
10670
10839
|
}
|
|
@@ -10992,8 +11161,8 @@ class ItemProperty {
|
|
|
10992
11161
|
propertyRecordSchema,
|
|
10993
11162
|
});
|
|
10994
11163
|
// Update instance fields to match new schema (mirror constructor logic)
|
|
10995
|
-
this._dataType = propertyRecordSchema.dataType;
|
|
10996
|
-
if (propertyRecordSchema.dataType
|
|
11164
|
+
this._dataType = normalizeDataType(propertyRecordSchema.dataType);
|
|
11165
|
+
if (isDataType(propertyRecordSchema.dataType, exports.ModelPropertyDataTypes.Relation)) {
|
|
10997
11166
|
;
|
|
10998
11167
|
this._isRelation = true;
|
|
10999
11168
|
}
|
|
@@ -11001,7 +11170,7 @@ class ItemProperty {
|
|
|
11001
11170
|
;
|
|
11002
11171
|
this._isRelation = false;
|
|
11003
11172
|
}
|
|
11004
|
-
if (propertyRecordSchema.dataType
|
|
11173
|
+
if (isDataType(propertyRecordSchema.dataType, exports.ModelPropertyDataTypes.List)) {
|
|
11005
11174
|
;
|
|
11006
11175
|
this._isList = true;
|
|
11007
11176
|
this._isRelation = !!(propertyRecordSchema.ref);
|
|
@@ -11073,11 +11242,11 @@ class ItemProperty {
|
|
|
11073
11242
|
// but cached instance doesn't (e.g. Item constructor created from schema first, then loadOrCreateItem
|
|
11074
11243
|
// has metadata with refResolvedValue - we must not lose display data).
|
|
11075
11244
|
const ctx = instance._getSnapshotContext();
|
|
11076
|
-
const incomingSchema = props.propertyRecordSchema;
|
|
11245
|
+
const incomingSchema = normalizePropertyRecordSchema(props.propertyRecordSchema);
|
|
11077
11246
|
if (incomingSchema && !ctx.propertyRecordSchema) {
|
|
11078
|
-
instance._dataType = incomingSchema.dataType;
|
|
11079
|
-
instance._isRelation = incomingSchema.dataType
|
|
11080
|
-
instance._isList = incomingSchema.dataType
|
|
11247
|
+
instance._dataType = normalizeDataType(incomingSchema.dataType);
|
|
11248
|
+
instance._isRelation = isDataType(incomingSchema.dataType, exports.ModelPropertyDataTypes.Relation);
|
|
11249
|
+
instance._isList = isDataType(incomingSchema.dataType, exports.ModelPropertyDataTypes.List);
|
|
11081
11250
|
instance._service.send({
|
|
11082
11251
|
type: 'updateContext',
|
|
11083
11252
|
propertyRecordSchema: incomingSchema,
|
|
@@ -11375,7 +11544,16 @@ class ItemProperty {
|
|
|
11375
11544
|
if (this._alias) {
|
|
11376
11545
|
return this._alias;
|
|
11377
11546
|
}
|
|
11378
|
-
|
|
11547
|
+
const context = this._getSnapshotContext();
|
|
11548
|
+
const name = context.propertyName || '';
|
|
11549
|
+
// Built under its schema key before the schema was known, then renamed to the storage name
|
|
11550
|
+
// (staff → staffIdentityIds) when a List-of-relation schema arrived: keep the schema key public.
|
|
11551
|
+
if (this._constructedPropertyName &&
|
|
11552
|
+
name !== this._constructedPropertyName &&
|
|
11553
|
+
listRelationEasPropertyName(this._constructedPropertyName, context.propertyRecordSchema) === name) {
|
|
11554
|
+
return this._constructedPropertyName;
|
|
11555
|
+
}
|
|
11556
|
+
return name;
|
|
11379
11557
|
}
|
|
11380
11558
|
/** DB / EAS / metadata column name (e.g. authorIdentityIds). Use for storage; prefer `propertyName` for public API. */
|
|
11381
11559
|
get storagePropertyName() {
|
|
@@ -11412,7 +11590,7 @@ class ItemProperty {
|
|
|
11412
11590
|
get status() {
|
|
11413
11591
|
return this._getSnapshot().value;
|
|
11414
11592
|
}
|
|
11415
|
-
/** Validation errors from last failed save (enum, pattern, minLength, maxLength). Cleared
|
|
11593
|
+
/** Validation errors from last failed save (enum, pattern, minLength, maxLength). Cleared when the next save starts. */
|
|
11416
11594
|
get saveValidationErrors() {
|
|
11417
11595
|
return this._getSnapshotContext()._saveValidationErrors ?? [];
|
|
11418
11596
|
}
|
|
@@ -11450,11 +11628,17 @@ class ItemProperty {
|
|
|
11450
11628
|
// If no propertyRecordSchema, try to resolve from Model before persisting (fixes external app persistence)
|
|
11451
11629
|
if (!context.propertyRecordSchema) {
|
|
11452
11630
|
const { modelName, propertyName, modelType } = context;
|
|
11453
|
-
|
|
11454
|
-
if (schema)
|
|
11455
|
-
|
|
11456
|
-
|
|
11457
|
-
}
|
|
11631
|
+
const pending = resolvePropertyRecordSchemaFromModel(modelName ?? '', propertyName ?? '', modelType).then((schema) => {
|
|
11632
|
+
if (!schema)
|
|
11633
|
+
return false;
|
|
11634
|
+
this._service.send({ type: 'updateContext', propertyRecordSchema: schema });
|
|
11635
|
+
this._service.send({ type: 'save', newValue: value });
|
|
11636
|
+
return true;
|
|
11637
|
+
}, () => false);
|
|
11638
|
+
this._pendingSchemaSave = pending;
|
|
11639
|
+
void pending.finally(() => {
|
|
11640
|
+
if (this._pendingSchemaSave === pending)
|
|
11641
|
+
this._pendingSchemaSave = undefined;
|
|
11458
11642
|
});
|
|
11459
11643
|
}
|
|
11460
11644
|
else {
|
|
@@ -11484,9 +11668,23 @@ class ItemProperty {
|
|
|
11484
11668
|
seedLocalId: ctx?.seedLocalId ?? undefined,
|
|
11485
11669
|
seedUid: ctx?.seedUid ?? undefined,
|
|
11486
11670
|
});
|
|
11487
|
-
|
|
11671
|
+
// Without this, save() would see `idle` before the deferred `save` event and resolve unsaved.
|
|
11672
|
+
if (this._pendingSchemaSave && !(await this._pendingSchemaSave)) {
|
|
11673
|
+
throw new Error(`Failed to save property ${ctx?.propertyName}: no schema found for ${ctx?.modelName}.${ctx?.propertyName}`);
|
|
11674
|
+
}
|
|
11675
|
+
const settled = await xstate.waitFor(this._service, (snapshot) => !snapshot.context.isSaving && snapshot.value === 'idle', {
|
|
11488
11676
|
timeout: 10000,
|
|
11489
11677
|
});
|
|
11678
|
+
const { _saveError: saveError, _saveValidationErrors: validationErrors, propertyName } = settled.context;
|
|
11679
|
+
if (saveError) {
|
|
11680
|
+
const error = new Error(`Failed to save property ${propertyName}: ${saveError.message}`);
|
|
11681
|
+
if (saveError.name)
|
|
11682
|
+
error.name = saveError.name;
|
|
11683
|
+
throw error;
|
|
11684
|
+
}
|
|
11685
|
+
if (validationErrors?.length) {
|
|
11686
|
+
throw new ItemPropertySaveValidationError(`Invalid value for property ${propertyName}: ${validationErrors.map((e) => e.message).join('; ')}`, validationErrors);
|
|
11687
|
+
}
|
|
11490
11688
|
const canonicalId = ctx?.seedLocalId ?? ctx?.seedUid;
|
|
11491
11689
|
if (canonicalId) {
|
|
11492
11690
|
eventEmitter.emit('itemProperty.saved', { seedLocalId: ctx.seedLocalId, seedUid: ctx.seedUid });
|
|
@@ -11511,6 +11709,14 @@ class ItemProperty {
|
|
|
11511
11709
|
if (cacheKey && cacheKey !== 'Item__') {
|
|
11512
11710
|
cacheKeys.push(cacheKey);
|
|
11513
11711
|
}
|
|
11712
|
+
// Renamed after construction (List of relation): also drop the entry cached under the old name.
|
|
11713
|
+
const publicName = this.propertyName;
|
|
11714
|
+
if (publicName && publicName !== context.propertyName) {
|
|
11715
|
+
const aliasKey = ItemProperty.cacheKey(context.seedUid || context.seedLocalId || '', publicName);
|
|
11716
|
+
if (aliasKey && aliasKey !== 'Item__' && ItemProperty.instanceCache.get(aliasKey)?.instance === this) {
|
|
11717
|
+
cacheKeys.push(aliasKey);
|
|
11718
|
+
}
|
|
11719
|
+
}
|
|
11514
11720
|
unloadEntity(this, {
|
|
11515
11721
|
getCacheKeys: () => cacheKeys,
|
|
11516
11722
|
caches: [ItemProperty.instanceCache],
|
|
@@ -11604,7 +11810,8 @@ ItemProperty.instanceCache = new Map();
|
|
|
11604
11810
|
|
|
11605
11811
|
var ItemProperty$1 = /*#__PURE__*/Object.freeze({
|
|
11606
11812
|
__proto__: null,
|
|
11607
|
-
ItemProperty: ItemProperty
|
|
11813
|
+
ItemProperty: ItemProperty,
|
|
11814
|
+
ItemPropertySaveValidationError: ItemPropertySaveValidationError
|
|
11608
11815
|
});
|
|
11609
11816
|
|
|
11610
11817
|
// Dynamic import to break circular dependency: Model -> BaseItem -> createNewItem -> Model
|
|
@@ -11790,6 +11997,15 @@ const getModel = () => {
|
|
|
11790
11997
|
};
|
|
11791
11998
|
// Define tracked properties for the Proxy
|
|
11792
11999
|
// These properties will be read from/written to the actor context
|
|
12000
|
+
/** Raw File/Image/Html content (not already a storage seed reference) needs ItemProperty.save(). */
|
|
12001
|
+
function needsStorageSavePipeline(dataType, value) {
|
|
12002
|
+
if (value == null || value === '')
|
|
12003
|
+
return false;
|
|
12004
|
+
const isStorageType = isDataType(dataType, exports.ModelPropertyDataTypes.File) ||
|
|
12005
|
+
isDataType(dataType, exports.ModelPropertyDataTypes.Image) ||
|
|
12006
|
+
isDataType(dataType, exports.ModelPropertyDataTypes.Html);
|
|
12007
|
+
return isStorageType && !isStorageSeedRef(value);
|
|
12008
|
+
}
|
|
11793
12009
|
const TRACKED_PROPERTIES$1 = [
|
|
11794
12010
|
'seedLocalId',
|
|
11795
12011
|
'seedUid',
|
|
@@ -11881,12 +12097,12 @@ class Item {
|
|
|
11881
12097
|
};
|
|
11882
12098
|
this.getPublishUploads = async (options) => {
|
|
11883
12099
|
// Use dynamic import to break circular dependency
|
|
11884
|
-
const getPublishUploadsMod = await Promise.resolve().then(function () { return require('./getPublishUploads-
|
|
12100
|
+
const getPublishUploadsMod = await Promise.resolve().then(function () { return require('./getPublishUploads-DMhCCKYF.js'); });
|
|
11885
12101
|
const { getPublishUploads } = getPublishUploadsMod;
|
|
11886
12102
|
return await getPublishUploads(this, [], undefined, options);
|
|
11887
12103
|
};
|
|
11888
12104
|
this.getPublishPayload = async (uploadedTransactions, options) => {
|
|
11889
|
-
const getPublishPayloadMod = await Promise.resolve().then(function () { return require('./getPublishPayload-
|
|
12105
|
+
const getPublishPayloadMod = await Promise.resolve().then(function () { return require('./getPublishPayload-D5DhLGvN.js'); });
|
|
11890
12106
|
const { getPublishPayload } = getPublishPayloadMod;
|
|
11891
12107
|
return await getPublishPayload(this, uploadedTransactions, options);
|
|
11892
12108
|
};
|
|
@@ -12347,6 +12563,7 @@ class Item {
|
|
|
12347
12563
|
const schemaName = props.schemaName;
|
|
12348
12564
|
// Get property names directly from database to make Item independent from Model
|
|
12349
12565
|
let propertyNames = [];
|
|
12566
|
+
const dataTypeByPropertyName = new Map();
|
|
12350
12567
|
const db = BaseDb.getAppDb();
|
|
12351
12568
|
if (db && props.modelName) {
|
|
12352
12569
|
// Query properties table directly by model name
|
|
@@ -12375,13 +12592,20 @@ class Item {
|
|
|
12375
12592
|
}
|
|
12376
12593
|
if (modelRecords.length > 0 && modelRecords[0].id) {
|
|
12377
12594
|
const propertyRecords = await db
|
|
12378
|
-
.select({ name: properties.name })
|
|
12595
|
+
.select({ name: properties.name, dataType: properties.dataType })
|
|
12379
12596
|
.from(properties)
|
|
12380
12597
|
.where(drizzleOrm.eq(properties.modelId, modelRecords[0].id));
|
|
12381
12598
|
propertyNames = propertyRecords.map((r) => r.name).filter((name) => Boolean(name));
|
|
12599
|
+
for (const r of propertyRecords) {
|
|
12600
|
+
if (r.name && r.dataType)
|
|
12601
|
+
dataTypeByPropertyName.set(r.name, r.dataType);
|
|
12602
|
+
}
|
|
12382
12603
|
}
|
|
12383
12604
|
}
|
|
12384
12605
|
const modelPropertyData = { modelName: props.modelName };
|
|
12606
|
+
// File/Image/Html values that are raw content (html string, data URI, URL, File) must go through
|
|
12607
|
+
// the property's save pipeline to become storage seeds; createNewItem would store them verbatim.
|
|
12608
|
+
const pipelineValues = [];
|
|
12385
12609
|
// Only include properties that are in the model schema
|
|
12386
12610
|
// Exclude modelInstance, modelName, and schemaName as they're metadata, not item properties
|
|
12387
12611
|
for (const [key, value] of Object.entries(props)) {
|
|
@@ -12390,6 +12614,10 @@ class Item {
|
|
|
12390
12614
|
continue;
|
|
12391
12615
|
}
|
|
12392
12616
|
if (propertyNames.length === 0 || propertyNames.includes(key)) {
|
|
12617
|
+
if (needsStorageSavePipeline(dataTypeByPropertyName.get(key), value)) {
|
|
12618
|
+
pipelineValues.push([key, value]);
|
|
12619
|
+
continue;
|
|
12620
|
+
}
|
|
12393
12621
|
// If we couldn't get property names from DB, include all properties
|
|
12394
12622
|
// Type assertion: we've filtered out modelInstance above, so value should be a valid property value
|
|
12395
12623
|
modelPropertyData[key] = value;
|
|
@@ -12398,6 +12626,11 @@ class Item {
|
|
|
12398
12626
|
const { seedLocalId, versionLocalId, } = await createNewItem(modelPropertyData);
|
|
12399
12627
|
props.seedLocalId = seedLocalId;
|
|
12400
12628
|
props.latestVersionLocalId = versionLocalId;
|
|
12629
|
+
// Don't seed property instances with raw storage content: the value setter skips unchanged
|
|
12630
|
+
// values, so savePipelineValues would never trigger a save.
|
|
12631
|
+
for (const [key] of pipelineValues) {
|
|
12632
|
+
delete props[key];
|
|
12633
|
+
}
|
|
12401
12634
|
// Item no longer needs modelInstance - it loads properties from database independently
|
|
12402
12635
|
// Exclude latestVersionUid from props as it has incompatible types (string vs VersionsType)
|
|
12403
12636
|
const { latestVersionUid, ...propsWithoutVersionUid } = props;
|
|
@@ -12497,7 +12730,8 @@ class Item {
|
|
|
12497
12730
|
},
|
|
12498
12731
|
});
|
|
12499
12732
|
this.registerItemInInstanceCache(proxiedInstance);
|
|
12500
|
-
|
|
12733
|
+
// Storage values must be saved before returning, so wait for readiness even when not requested.
|
|
12734
|
+
if (!waitForReady && pipelineValues.length === 0)
|
|
12501
12735
|
return proxiedInstance;
|
|
12502
12736
|
try {
|
|
12503
12737
|
await this.waitForItemInstanceReadyForRead(proxiedInstance, readyTimeout);
|
|
@@ -12511,8 +12745,46 @@ class Item {
|
|
|
12511
12745
|
}
|
|
12512
12746
|
throw err;
|
|
12513
12747
|
}
|
|
12748
|
+
await this.savePipelineValues(proxiedInstance, pipelineValues, readyTimeout);
|
|
12514
12749
|
return proxiedInstance;
|
|
12515
12750
|
}
|
|
12751
|
+
/**
|
|
12752
|
+
* Run each File/Image/Html initial value through its ItemProperty save pipeline (sequentially, to
|
|
12753
|
+
* avoid SQLite write contention). Rejects on the first failure; the item itself has been created.
|
|
12754
|
+
*/
|
|
12755
|
+
static async savePipelineValues(item, pipelineValues, timeout) {
|
|
12756
|
+
for (const [propertyName, value] of pipelineValues) {
|
|
12757
|
+
const property = await this.waitForPropertyInstance(item, propertyName, timeout);
|
|
12758
|
+
if (!property) {
|
|
12759
|
+
throw new Error(`Item.create: property ${item.modelName}.${propertyName} did not load for item ${item.seedLocalId}; value was not saved`);
|
|
12760
|
+
}
|
|
12761
|
+
property.value = value;
|
|
12762
|
+
try {
|
|
12763
|
+
await property.save();
|
|
12764
|
+
}
|
|
12765
|
+
catch (error) {
|
|
12766
|
+
throw new Error(`Item.create: failed to save ${item.modelName}.${propertyName} for item ${item.seedLocalId}: ` +
|
|
12767
|
+
(error instanceof Error ? error.message : String(error)), { cause: error });
|
|
12768
|
+
}
|
|
12769
|
+
}
|
|
12770
|
+
}
|
|
12771
|
+
static async waitForPropertyInstance(item, propertyName, timeout) {
|
|
12772
|
+
const find = (ctx) => {
|
|
12773
|
+
const instances = ctx?.propertyInstances;
|
|
12774
|
+
const altKey = getAlternatePropertyNameForInstanceLookup(propertyName);
|
|
12775
|
+
return instances?.get(propertyName) ?? (altKey ? instances?.get(altKey) : undefined);
|
|
12776
|
+
};
|
|
12777
|
+
const existing = find(item.getService().getSnapshot().context);
|
|
12778
|
+
if (existing)
|
|
12779
|
+
return existing;
|
|
12780
|
+
try {
|
|
12781
|
+
const snap = await xstate.waitFor(item.getService(), (s) => !!find(s.context), { timeout });
|
|
12782
|
+
return find(snap.context);
|
|
12783
|
+
}
|
|
12784
|
+
catch {
|
|
12785
|
+
return undefined;
|
|
12786
|
+
}
|
|
12787
|
+
}
|
|
12516
12788
|
/**
|
|
12517
12789
|
* Get Item instance by ID from cache
|
|
12518
12790
|
* The ID can be either seedUid or seedLocalId
|
|
@@ -13543,7 +13815,7 @@ const runEasSync = xstate.fromPromise(async ({ input, }) => {
|
|
|
13543
13815
|
requestPayload: input.requestPayload,
|
|
13544
13816
|
persistedSnapshot: input.runningSnapshot,
|
|
13545
13817
|
});
|
|
13546
|
-
const { runSyncFromEas } = await Promise.resolve().then(function () { return require('./syncDbWithEas-
|
|
13818
|
+
const { runSyncFromEas } = await Promise.resolve().then(function () { return require('./syncDbWithEas-C6n34o_Q.js'); });
|
|
13547
13819
|
try {
|
|
13548
13820
|
await runSyncFromEas(toRunSyncArg(input.options));
|
|
13549
13821
|
await finalizeEasSyncProcessRow(rowId, {
|
|
@@ -13760,10 +14032,10 @@ var easSyncManager = /*#__PURE__*/Object.freeze({
|
|
|
13760
14032
|
startEasSyncActor: startEasSyncActor
|
|
13761
14033
|
});
|
|
13762
14034
|
|
|
13763
|
-
const logger$
|
|
14035
|
+
const logger$e = debug('seedSdk:services:events');
|
|
13764
14036
|
const handleServiceSaveState = (event) => {
|
|
13765
14037
|
const { state, serviceId } = event;
|
|
13766
|
-
logger$
|
|
14038
|
+
logger$e(`[browser] [service.saveState.request] serviceId: ${serviceId}`);
|
|
13767
14039
|
// TODO: This is called from Node as well. Do we need it? If so, need to generalize this to all platforms.
|
|
13768
14040
|
// localStorage.setItem(`seed_sdk_service_${serviceId}`, JSON.stringify(state))
|
|
13769
14041
|
};
|
|
@@ -13847,9 +14119,32 @@ class BasePathResolver {
|
|
|
13847
14119
|
}
|
|
13848
14120
|
BasePathResolver._impl = null;
|
|
13849
14121
|
|
|
13850
|
-
|
|
14122
|
+
/**
|
|
14123
|
+
* On Node, storage uses `filesDir`. `endpoints.filePaths` and `endpoints.files` are
|
|
14124
|
+
* required by init but have no separate Node consumer, so fill them from `filesDir`.
|
|
14125
|
+
* Browser configs are left unchanged.
|
|
14126
|
+
*/
|
|
14127
|
+
function normalizeSeedConfigEndpoints(config) {
|
|
14128
|
+
if (!config)
|
|
14129
|
+
return config;
|
|
14130
|
+
const endpoints = config.endpoints;
|
|
14131
|
+
if (endpoints?.filePaths && endpoints?.files)
|
|
14132
|
+
return config;
|
|
14133
|
+
if (!(isNode() && !isBrowser()))
|
|
14134
|
+
return config;
|
|
14135
|
+
const filesDir = config.filesDir;
|
|
14136
|
+
if (!filesDir)
|
|
14137
|
+
return config;
|
|
14138
|
+
const next = {
|
|
14139
|
+
filePaths: endpoints?.filePaths || filesDir,
|
|
14140
|
+
files: endpoints?.files || filesDir,
|
|
14141
|
+
};
|
|
14142
|
+
return { ...config, endpoints: next };
|
|
14143
|
+
}
|
|
14144
|
+
|
|
14145
|
+
const logger$d = debug('seedSdk:ClientManager:initialize');
|
|
13851
14146
|
const platformClassesInit = xstate.fromCallback(({ sendBack, input: { context, event } }) => {
|
|
13852
|
-
logger$
|
|
14147
|
+
logger$d('initialize from ClientManager');
|
|
13853
14148
|
const { isInitialized } = context;
|
|
13854
14149
|
if (!event || !('options' in event)) {
|
|
13855
14150
|
throw new Error('Initialize event must include options');
|
|
@@ -13873,8 +14168,10 @@ const platformClassesInit = xstate.fromCallback(({ sendBack, input: { context, e
|
|
|
13873
14168
|
if (cancelled) {
|
|
13874
14169
|
return;
|
|
13875
14170
|
}
|
|
13876
|
-
const {
|
|
13877
|
-
|
|
14171
|
+
const { addresses } = options;
|
|
14172
|
+
const config = normalizeSeedConfigEndpoints(options.config);
|
|
14173
|
+
// Validate required endpoints - this should happen early in the initialization process.
|
|
14174
|
+
// Node fills these from filesDir; browser callers still pass them.
|
|
13878
14175
|
if (!config?.endpoints || !config.endpoints.filePaths || !config.endpoints.files) {
|
|
13879
14176
|
throw new Error('Config must include endpoints with filePaths and files');
|
|
13880
14177
|
}
|
|
@@ -13896,13 +14193,20 @@ const platformClassesInit = xstate.fromCallback(({ sendBack, input: { context, e
|
|
|
13896
14193
|
if (cancelled) {
|
|
13897
14194
|
return;
|
|
13898
14195
|
}
|
|
13899
|
-
const { models, endpoints, arweaveDomain, dbConfig, filesDir, schemaFile, schema, gateway, uploadApiBaseUrl } = config;
|
|
14196
|
+
const { models, endpoints, arweaveDomain, dbConfig, filesDir, schemaFile, schema, gateway, uploadApiBaseUrl, eas: eas$1 } = config;
|
|
14197
|
+
if (eas$1) {
|
|
14198
|
+
eas.configureEasReadChain('sdk', { chainId: eas$1.chainId, indexerUrl: eas$1.indexerUrl });
|
|
14199
|
+
}
|
|
13900
14200
|
const gatewayConfig = arweave.seedGatewayConfigFromSeedConfig({
|
|
13901
14201
|
...config,
|
|
13902
14202
|
arweaveDomain,
|
|
13903
14203
|
uploadApiBaseUrl,
|
|
13904
14204
|
gateway,
|
|
13905
14205
|
});
|
|
14206
|
+
// Only when configured, so a host app's own setPreferredArweaveReadBaseUrls() call survives init.
|
|
14207
|
+
if (gatewayConfig.preferredReadBaseUrls) {
|
|
14208
|
+
arweave.setPreferredArweaveReadBaseUrls(gatewayConfig.preferredReadBaseUrls);
|
|
14209
|
+
}
|
|
13906
14210
|
const resolvedGateway = await arweave.resolveSeedGatewayEndpoints(gatewayConfig);
|
|
13907
14211
|
arweave.setResolvedSeedGatewayEndpoints(resolvedGateway);
|
|
13908
14212
|
arweave.BaseArweaveClient.setHost(`${resolvedGateway.arweaveProtocol}://${resolvedGateway.arweaveHost}`);
|
|
@@ -14008,7 +14312,7 @@ const platformClassesInit = xstate.fromCallback(({ sendBack, input: { context, e
|
|
|
14008
14312
|
};
|
|
14009
14313
|
});
|
|
14010
14314
|
|
|
14011
|
-
const logger$
|
|
14315
|
+
const logger$c = debug('seedSdk:client:writeToDb');
|
|
14012
14316
|
const saveAppState = xstate.fromCallback(({ sendBack, input: { key, value } }) => {
|
|
14013
14317
|
const _saveAppState = async () => {
|
|
14014
14318
|
try {
|
|
@@ -14016,7 +14320,7 @@ const saveAppState = xstate.fromCallback(({ sendBack, input: { key, value } }) =
|
|
|
14016
14320
|
if (!appDb) {
|
|
14017
14321
|
// In test environments, continue anyway
|
|
14018
14322
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
14019
|
-
logger$
|
|
14323
|
+
logger$c('[client/actors] [saveAppState] App DB not found, but continuing in test environment');
|
|
14020
14324
|
return;
|
|
14021
14325
|
}
|
|
14022
14326
|
throw new Error('App DB not found');
|
|
@@ -14032,13 +14336,13 @@ const saveAppState = xstate.fromCallback(({ sendBack, input: { key, value } }) =
|
|
|
14032
14336
|
value: JSON.stringify(value),
|
|
14033
14337
|
},
|
|
14034
14338
|
});
|
|
14035
|
-
logger$
|
|
14339
|
+
logger$c('result', result);
|
|
14036
14340
|
}
|
|
14037
14341
|
catch (error) {
|
|
14038
|
-
logger$
|
|
14342
|
+
logger$c('[client/actors] [saveAppState] Error saving app state:', error);
|
|
14039
14343
|
// In test environments, continue anyway
|
|
14040
14344
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
14041
|
-
logger$
|
|
14345
|
+
logger$c('[client/actors] [saveAppState] Continuing despite error in test environment');
|
|
14042
14346
|
return;
|
|
14043
14347
|
}
|
|
14044
14348
|
throw error;
|
|
@@ -14053,10 +14357,10 @@ const saveAppState = xstate.fromCallback(({ sendBack, input: { key, value } }) =
|
|
|
14053
14357
|
});
|
|
14054
14358
|
})
|
|
14055
14359
|
.catch((error) => {
|
|
14056
|
-
logger$
|
|
14360
|
+
logger$c('[client/actors] [saveAppState] Error in promise chain:', error);
|
|
14057
14361
|
// In test environments, still send success to allow state machine to progress
|
|
14058
14362
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
14059
|
-
logger$
|
|
14363
|
+
logger$c('[client/actors] [saveAppState] Sending success despite error in test environment');
|
|
14060
14364
|
sendBack({
|
|
14061
14365
|
type: 'saveAppStateSuccess',
|
|
14062
14366
|
key,
|
|
@@ -14126,7 +14430,7 @@ const fileSystemInit = xstate.fromCallback(({ sendBack, input: { context }, }) =
|
|
|
14126
14430
|
};
|
|
14127
14431
|
});
|
|
14128
14432
|
|
|
14129
|
-
const logger$
|
|
14433
|
+
const logger$b = debug('seedSdk:client:actors:dbInit');
|
|
14130
14434
|
const dbInit = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
14131
14435
|
const _dbInit = async () => {
|
|
14132
14436
|
const { filesDir } = context;
|
|
@@ -14140,14 +14444,14 @@ const dbInit = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
|
14140
14444
|
if (!appDb) {
|
|
14141
14445
|
throw new Error('Database not available after preparation');
|
|
14142
14446
|
}
|
|
14143
|
-
logger$
|
|
14447
|
+
logger$b('[client/actors] [dbInit] Database prepared and ready');
|
|
14144
14448
|
};
|
|
14145
14449
|
_dbInit()
|
|
14146
14450
|
.then(() => {
|
|
14147
14451
|
sendBack({ type: ClientManagerEvents.DB_READY });
|
|
14148
14452
|
})
|
|
14149
14453
|
.catch((error) => {
|
|
14150
|
-
logger$
|
|
14454
|
+
logger$b('Error in dbInit:', error);
|
|
14151
14455
|
sendBack({
|
|
14152
14456
|
type: 'error',
|
|
14153
14457
|
error: error instanceof Error ? error : new Error(String(error))
|
|
@@ -14155,7 +14459,7 @@ const dbInit = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
|
14155
14459
|
});
|
|
14156
14460
|
});
|
|
14157
14461
|
|
|
14158
|
-
const logger$
|
|
14462
|
+
const logger$a = debug('seedSdk:client:actors:addModelsToStore');
|
|
14159
14463
|
const addModelsToStore = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
14160
14464
|
const _addModelsToStore = async () => {
|
|
14161
14465
|
let { models } = context;
|
|
@@ -14169,7 +14473,7 @@ const addModelsToStore = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
14169
14473
|
// Models are now Model instances, no registration needed
|
|
14170
14474
|
// They should be created via Model.create() and are accessible via Model static methods
|
|
14171
14475
|
for (const [key] of Object.entries(allModels)) {
|
|
14172
|
-
logger$
|
|
14476
|
+
logger$a('model available:', key);
|
|
14173
14477
|
}
|
|
14174
14478
|
};
|
|
14175
14479
|
_addModelsToStore()
|
|
@@ -14177,7 +14481,7 @@ const addModelsToStore = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
14177
14481
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_STORE_SUCCESS });
|
|
14178
14482
|
})
|
|
14179
14483
|
.catch((error) => {
|
|
14180
|
-
logger$
|
|
14484
|
+
logger$a('[client/actors] [addModelsToStore] Error:', error);
|
|
14181
14485
|
sendBack({
|
|
14182
14486
|
type: 'error',
|
|
14183
14487
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
@@ -14185,7 +14489,7 @@ const addModelsToStore = xstate.fromCallback(({ sendBack, input: { context } })
|
|
|
14185
14489
|
});
|
|
14186
14490
|
});
|
|
14187
14491
|
|
|
14188
|
-
const logger$
|
|
14492
|
+
const logger$9 = debug('seedSdk:client:actors:addModelsToDb');
|
|
14189
14493
|
const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
14190
14494
|
const { models } = context;
|
|
14191
14495
|
const _addModelsToDb = async () => {
|
|
@@ -14223,14 +14527,14 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
14223
14527
|
existingByName.set(m.name, m);
|
|
14224
14528
|
}
|
|
14225
14529
|
for (const name of modelsToInsert) {
|
|
14226
|
-
logger$
|
|
14530
|
+
logger$9('[client/actors] [addModelsToDb] inserted model:', name);
|
|
14227
14531
|
}
|
|
14228
14532
|
}
|
|
14229
14533
|
let hasModelsInDb = true;
|
|
14230
14534
|
for (const modelName of modelNames) {
|
|
14231
14535
|
const foundModel = existingByName.get(modelName);
|
|
14232
14536
|
if (!foundModel) {
|
|
14233
|
-
logger$
|
|
14537
|
+
logger$9('[client/actors] [addModelsToDb] Warning: Could not find or create model:', modelName);
|
|
14234
14538
|
hasModelsInDb = false;
|
|
14235
14539
|
continue;
|
|
14236
14540
|
}
|
|
@@ -14241,7 +14545,7 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
14241
14545
|
}
|
|
14242
14546
|
// If we have no models to process, still send success (empty models is valid)
|
|
14243
14547
|
if (schemaDefsByModelName.size === 0) {
|
|
14244
|
-
logger$
|
|
14548
|
+
logger$9('[client/actors] [addModelsToDb] No models to process, but continuing');
|
|
14245
14549
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
|
|
14246
14550
|
return;
|
|
14247
14551
|
}
|
|
@@ -14284,15 +14588,15 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
14284
14588
|
requestEasSyncFromModelsInit();
|
|
14285
14589
|
}
|
|
14286
14590
|
else {
|
|
14287
|
-
logger$
|
|
14591
|
+
logger$9('[client/actors] [addModelsToDb] No schemas found from EAS, but continuing');
|
|
14288
14592
|
}
|
|
14289
14593
|
}
|
|
14290
14594
|
catch (error) {
|
|
14291
14595
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
14292
|
-
logger$
|
|
14596
|
+
logger$9('[client/actors] [addModelsToDb] Warning: Could not fetch schemas from EAS (background):', error.message);
|
|
14293
14597
|
}
|
|
14294
14598
|
else {
|
|
14295
|
-
logger$
|
|
14599
|
+
logger$9('[client/actors] [addModelsToDb] Error fetching schemas (background):', error.message);
|
|
14296
14600
|
}
|
|
14297
14601
|
}
|
|
14298
14602
|
};
|
|
@@ -14304,10 +14608,10 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
14304
14608
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
|
|
14305
14609
|
})
|
|
14306
14610
|
.catch((error) => {
|
|
14307
|
-
logger$
|
|
14611
|
+
logger$9('[client/actors] [addModelsToDb] Error:', error);
|
|
14308
14612
|
// In test environments, still send success to allow initialization to complete
|
|
14309
14613
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
14310
|
-
logger$
|
|
14614
|
+
logger$9('[client/actors] [addModelsToDb] Continuing despite error in test environment');
|
|
14311
14615
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
|
|
14312
14616
|
}
|
|
14313
14617
|
else {
|
|
@@ -14320,6 +14624,102 @@ const addModelsToDb = xstate.fromCallback(({ sendBack, input: { context } }) =>
|
|
|
14320
14624
|
return () => { };
|
|
14321
14625
|
});
|
|
14322
14626
|
|
|
14627
|
+
const logger$8 = debug('seedSdk:helpers:localDbChain');
|
|
14628
|
+
/** appState key recording which EAS chain the local database holds attestations from. */
|
|
14629
|
+
const EAS_CHAIN_ID_APP_STATE_KEY = 'easChainId';
|
|
14630
|
+
/**
|
|
14631
|
+
* Databases written before the chain was recorded only ever held Optimism Sepolia data
|
|
14632
|
+
* (the only chain the SDK supported then).
|
|
14633
|
+
*/
|
|
14634
|
+
const LEGACY_CHAIN_ID = eas.DEFAULT_EAS_CHAIN_ID;
|
|
14635
|
+
async function readRecordedChainId(appDb) {
|
|
14636
|
+
const rows = await appDb
|
|
14637
|
+
.select({ value: appState.value })
|
|
14638
|
+
.from(appState)
|
|
14639
|
+
.where(drizzleOrm.eq(appState.key, EAS_CHAIN_ID_APP_STATE_KEY))
|
|
14640
|
+
.limit(1);
|
|
14641
|
+
const parsed = Number(rows[0]?.value);
|
|
14642
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
14643
|
+
}
|
|
14644
|
+
async function recordChainId(appDb, chainId) {
|
|
14645
|
+
const value = String(chainId);
|
|
14646
|
+
await appDb
|
|
14647
|
+
.insert(appState)
|
|
14648
|
+
.values({ key: EAS_CHAIN_ID_APP_STATE_KEY, value })
|
|
14649
|
+
.onConflictDoUpdate({ target: appState.key, set: { value } });
|
|
14650
|
+
}
|
|
14651
|
+
async function hasOnChainData(appDb) {
|
|
14652
|
+
const rows = await appDb
|
|
14653
|
+
.select({ uid: seeds.uid })
|
|
14654
|
+
.from(seeds)
|
|
14655
|
+
.where(drizzleOrm.and(drizzleOrm.isNotNull(seeds.uid), drizzleOrm.ne(seeds.uid, '')))
|
|
14656
|
+
.limit(1);
|
|
14657
|
+
return rows.length > 0;
|
|
14658
|
+
}
|
|
14659
|
+
/**
|
|
14660
|
+
* Chain the local DB holds data from: the recorded one, or Optimism Sepolia for an unrecorded
|
|
14661
|
+
* DB that already has attestations. Records the legacy value so later checks are cheap.
|
|
14662
|
+
*/
|
|
14663
|
+
async function resolveLocalDbChainId(appDb) {
|
|
14664
|
+
const recorded = await readRecordedChainId(appDb);
|
|
14665
|
+
if (recorded !== undefined)
|
|
14666
|
+
return recorded;
|
|
14667
|
+
if (await hasOnChainData(appDb)) {
|
|
14668
|
+
await recordChainId(appDb, LEGACY_CHAIN_ID);
|
|
14669
|
+
return LEGACY_CHAIN_ID;
|
|
14670
|
+
}
|
|
14671
|
+
return undefined;
|
|
14672
|
+
}
|
|
14673
|
+
/** How long EAS sync waits for `initPublish` to set the chain before using the current one. */
|
|
14674
|
+
const EAS_CHAIN_SETTLE_TIMEOUT_MS = 30000;
|
|
14675
|
+
/**
|
|
14676
|
+
* Wait until the read chain is known before syncing. Only waits when `@seedprotocol/publish`
|
|
14677
|
+
* is loaded but `initPublish` has not run, and no chain is configured or recorded locally.
|
|
14678
|
+
*/
|
|
14679
|
+
async function waitForEasReadChain(timeoutMs = EAS_CHAIN_SETTLE_TIMEOUT_MS) {
|
|
14680
|
+
if (await eas.whenEasReadChainSettled(timeoutMs))
|
|
14681
|
+
return;
|
|
14682
|
+
console.warn(`[Seed Protocol] EAS sync waited ${Math.round(timeoutMs / 1000)}s for initPublish to set the chain and is continuing on chain ${eas.getEasReadChainId()}. Set SeedConfig.eas.chainId to skip the wait.`);
|
|
14683
|
+
}
|
|
14684
|
+
/**
|
|
14685
|
+
* Called at SDK init once the DB is ready. Registers the DB's chain with the EAS read side so
|
|
14686
|
+
* reads start on that chain even before publish is initialized, and throws when SeedConfig.eas
|
|
14687
|
+
* or PublishConfig.chain names a different chain. An empty DB is recorded only when a chain
|
|
14688
|
+
* is configured explicitly; otherwise the first sync or publish records it.
|
|
14689
|
+
*/
|
|
14690
|
+
async function loadLocalDbChain() {
|
|
14691
|
+
const appDb = BaseDb.getAppDb();
|
|
14692
|
+
if (!appDb)
|
|
14693
|
+
return;
|
|
14694
|
+
const localChainId = await resolveLocalDbChainId(appDb);
|
|
14695
|
+
if (localChainId !== undefined) {
|
|
14696
|
+
eas.configureEasReadChain('localDb', { chainId: localChainId });
|
|
14697
|
+
logger$8('local DB holds chain %d', localChainId);
|
|
14698
|
+
return;
|
|
14699
|
+
}
|
|
14700
|
+
if (eas.isEasReadChainConfigured()) {
|
|
14701
|
+
const chainId = eas.getEasReadChainId();
|
|
14702
|
+
await recordChainId(appDb, chainId);
|
|
14703
|
+
eas.configureEasReadChain('localDb', { chainId });
|
|
14704
|
+
}
|
|
14705
|
+
}
|
|
14706
|
+
/**
|
|
14707
|
+
* Call before writing chain data to the local DB (EAS sync, publish, revoke). Records the
|
|
14708
|
+
* current chain on an empty DB; throws when the DB holds data from a different chain.
|
|
14709
|
+
*/
|
|
14710
|
+
async function assertLocalDbChain() {
|
|
14711
|
+
const appDb = BaseDb.getAppDb();
|
|
14712
|
+
if (!appDb)
|
|
14713
|
+
return;
|
|
14714
|
+
const chainId = eas.getEasReadChainId();
|
|
14715
|
+
const localChainId = await resolveLocalDbChainId(appDb);
|
|
14716
|
+
if (localChainId === undefined) {
|
|
14717
|
+
await recordChainId(appDb, chainId);
|
|
14718
|
+
}
|
|
14719
|
+
// Throws with a remediation message when the local chain differs from the configured one.
|
|
14720
|
+
eas.configureEasReadChain('localDb', { chainId: localChainId ?? chainId });
|
|
14721
|
+
}
|
|
14722
|
+
|
|
14323
14723
|
const logger$7 = debug('seedSdk:client:actors:saveConfig');
|
|
14324
14724
|
const saveConfig = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
14325
14725
|
logger$7('saveConfig starting');
|
|
@@ -14402,6 +14802,8 @@ const saveConfig = xstate.fromCallback(({ sendBack, input: { context } }) => {
|
|
|
14402
14802
|
await persistKey('gatewaySidecarPort', String(gatewaySidecarPort));
|
|
14403
14803
|
}
|
|
14404
14804
|
await persistKey('gatewayProxyBaseUrl', gatewayProxyBaseUrl);
|
|
14805
|
+
// Throws when the DB holds attestations from a different chain than the one configured.
|
|
14806
|
+
await loadLocalDbChain();
|
|
14405
14807
|
}
|
|
14406
14808
|
catch (error) {
|
|
14407
14809
|
logger$7('[internal/actors] [saveConfig] Error saving config:', error);
|
|
@@ -18127,7 +18529,7 @@ const saveDraftLogger = debug('seedSdk:model:saveDraftToDb');
|
|
|
18127
18529
|
// Lazy import cache for ModelProperty to avoid circular dependency
|
|
18128
18530
|
// Eagerly start loading to minimize delay on first access
|
|
18129
18531
|
let ModelPropertyClass = null;
|
|
18130
|
-
const modelPropertyImportPromise = Promise.resolve().then(function () { return require('./ModelProperty-
|
|
18532
|
+
const modelPropertyImportPromise = Promise.resolve().then(function () { return require('./ModelProperty-D9FGaGuE.js'); })
|
|
18131
18533
|
.then(module => {
|
|
18132
18534
|
ModelPropertyClass = module.ModelProperty;
|
|
18133
18535
|
return ModelPropertyClass;
|
|
@@ -18144,7 +18546,7 @@ function getModelProperty() {
|
|
|
18144
18546
|
}
|
|
18145
18547
|
// Lazy import cache for Schema to avoid circular dependency
|
|
18146
18548
|
let SchemaClass = null;
|
|
18147
|
-
const schemaImportPromise = Promise.resolve().then(function () { return require('./Schema-
|
|
18549
|
+
const schemaImportPromise = Promise.resolve().then(function () { return require('./Schema-BiJIPLEL.js'); })
|
|
18148
18550
|
.then(module => {
|
|
18149
18551
|
SchemaClass = module.Schema;
|
|
18150
18552
|
return SchemaClass;
|
|
@@ -19879,8 +20281,9 @@ class NodeFileManager {
|
|
|
19879
20281
|
getFsSync() {
|
|
19880
20282
|
return fs__namespace;
|
|
19881
20283
|
}
|
|
19882
|
-
|
|
19883
|
-
|
|
20284
|
+
/** Node has no blob URLs; a file:// URL keeps refResolvedDisplayValue meaningful for server callers. */
|
|
20285
|
+
async getContentUrlFromPath(filePath) {
|
|
20286
|
+
return url.pathToFileURL(path.resolve(filePath)).href;
|
|
19884
20287
|
}
|
|
19885
20288
|
async initializeFileSystem(_workingDir) {
|
|
19886
20289
|
return; // No need to initialize file system in node
|
|
@@ -20046,7 +20449,7 @@ function resolveSdkDrizzleMigrationsDir(sdkRootDir) {
|
|
|
20046
20449
|
})();
|
|
20047
20450
|
// Also resolve relative to this module so temp-cwd tests / odd roots still find
|
|
20048
20451
|
// packages/sdk/src/db/drizzle (or dist/db/drizzle after publish).
|
|
20049
|
-
const moduleDir = path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cjs/index-
|
|
20452
|
+
const moduleDir = path.dirname(node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cjs/index-CSNtEnbF.js', document.baseURI).href))));
|
|
20050
20453
|
const candidates = [
|
|
20051
20454
|
path.join(root, 'db', 'drizzle'), // production: sdkRoot is dist/
|
|
20052
20455
|
path.join(root, 'dist', 'db', 'drizzle'), // sdk package root with built dist
|
|
@@ -20116,7 +20519,7 @@ class NodeDb {
|
|
|
20116
20519
|
logger$1('[Db.prepareDb] running migrations from %s', outDir);
|
|
20117
20520
|
await migrator.migrate(db, { migrationsFolder: outDir });
|
|
20118
20521
|
this.db = db;
|
|
20119
|
-
const { backfillMetadataPropertyIds } = await Promise.resolve().then(function () { return require('./backfillMetadataPropertyIds-
|
|
20522
|
+
const { backfillMetadataPropertyIds } = await Promise.resolve().then(function () { return require('./backfillMetadataPropertyIds-2XaN3b9S.js'); });
|
|
20120
20523
|
await backfillMetadataPropertyIds();
|
|
20121
20524
|
return this.db;
|
|
20122
20525
|
}
|
|
@@ -20610,6 +21013,7 @@ exports.Image = Image;
|
|
|
20610
21013
|
exports.Item = Item;
|
|
20611
21014
|
exports.Item$1 = Item$1;
|
|
20612
21015
|
exports.ItemProperty = ItemProperty;
|
|
21016
|
+
exports.ItemPropertySaveValidationError = ItemPropertySaveValidationError;
|
|
20613
21017
|
exports.Json = Json;
|
|
20614
21018
|
exports.List = List;
|
|
20615
21019
|
exports.Model = Model;
|
|
@@ -20634,11 +21038,12 @@ exports.TPropertyDefs = TPropertyDefs;
|
|
|
20634
21038
|
exports.TStorageType = TStorageType;
|
|
20635
21039
|
exports.TValidationRules = TValidationRules;
|
|
20636
21040
|
exports.Text = Text;
|
|
20637
|
-
exports.
|
|
21041
|
+
exports.VERSION_SCHEMA_UID = VERSION_SCHEMA_UID;
|
|
20638
21042
|
exports.ZERO_BYTES32 = ZERO_BYTES32;
|
|
20639
21043
|
exports.addModelsToDb = addModelsToDb$1;
|
|
20640
21044
|
exports.addSchemaToDb = addSchemaToDb;
|
|
20641
21045
|
exports.appState = appState;
|
|
21046
|
+
exports.assertLocalDbChain = assertLocalDbChain;
|
|
20642
21047
|
exports.clearDestroySubscriptions = clearDestroySubscriptions;
|
|
20643
21048
|
exports.commandExists = commandExists;
|
|
20644
21049
|
exports.config = config;
|
|
@@ -20658,7 +21063,6 @@ exports.getAllAddressesFromDb = getAllAddressesFromDb;
|
|
|
20658
21063
|
exports.getClient = getClient;
|
|
20659
21064
|
exports.getContentHash = getContentHash;
|
|
20660
21065
|
exports.getCorrectId = getCorrectId;
|
|
20661
|
-
exports.getEasSchemaForItemProperty = getEasSchemaForItemProperty;
|
|
20662
21066
|
exports.getEasSchemaUidForModel = getEasSchemaUidForModel;
|
|
20663
21067
|
exports.getItemData = getItemData;
|
|
20664
21068
|
exports.getLatestPublishedVersionRow = getLatestPublishedVersionRow;
|
|
@@ -20670,8 +21074,12 @@ exports.getPropertyIdForModelAndName = getPropertyIdForModelAndName;
|
|
|
20670
21074
|
exports.getRefValueType = getRefValueType;
|
|
20671
21075
|
exports.htmlEmbeddedImageCoPublish = htmlEmbeddedImageCoPublish;
|
|
20672
21076
|
exports.importJsonSchema = importJsonSchema;
|
|
21077
|
+
exports.isDataType = isDataType;
|
|
20673
21078
|
exports.isInternalSchema = isInternalSchema;
|
|
21079
|
+
exports.isPublishedSeedRef = isPublishedSeedRef;
|
|
21080
|
+
exports.isStorageSeedRef = isStorageSeedRef;
|
|
20674
21081
|
exports.listCompleteSchemaFiles = listCompleteSchemaFiles;
|
|
21082
|
+
exports.listRelationEasPropertyName = listRelationEasPropertyName;
|
|
20675
21083
|
exports.loadAllSchemasFromDb = loadAllSchemasFromDb;
|
|
20676
21084
|
exports.loadModelsFromDbForSchema = loadModelsFromDbForSchema;
|
|
20677
21085
|
exports.loadSchemaFromFile = loadSchemaFromFile;
|
|
@@ -20682,13 +21090,16 @@ exports.modelUids = modelUids;
|
|
|
20682
21090
|
exports.models = models$1;
|
|
20683
21091
|
exports.normalizeDataType = normalizeDataType;
|
|
20684
21092
|
exports.normalizeHexAddress = normalizeHexAddress;
|
|
21093
|
+
exports.normalizePropertyRecordSchema = normalizePropertyRecordSchema;
|
|
20685
21094
|
exports.normalizePublisher = normalizePublisher;
|
|
21095
|
+
exports.normalizeRelationPropertyValue = normalizeRelationPropertyValue;
|
|
20686
21096
|
exports.parseListPropertyValueFromStorage = parseListPropertyValueFromStorage;
|
|
20687
21097
|
exports.parseMarkdownFrontmatter = parseMarkdownFrontmatter;
|
|
20688
21098
|
exports.processSeedConfig = processSeedConfig;
|
|
20689
21099
|
exports.properties = properties;
|
|
20690
21100
|
exports.readJsonImportFile = readJsonImportFile;
|
|
20691
21101
|
exports.resolveSdkDrizzleMigrationsDir = resolveSdkDrizzleMigrationsDir;
|
|
21102
|
+
exports.resolveSeedIdsFromRefString = resolveSeedIdsFromRefString;
|
|
20692
21103
|
exports.resolveStorageNameToSchemaName = resolveStorageNameToSchemaName;
|
|
20693
21104
|
exports.runDestroyLifecycle = runDestroyLifecycle;
|
|
20694
21105
|
exports.runSeedInit = runSeedInit;
|
|
@@ -20704,7 +21115,8 @@ exports.toSnakeCase = toSnakeCase;
|
|
|
20704
21115
|
exports.transformImportToSchemaFile = transformImportToSchemaFile;
|
|
20705
21116
|
exports.unloadEntity = unloadEntity;
|
|
20706
21117
|
exports.versions = versions;
|
|
21118
|
+
exports.waitForEasReadChain = waitForEasReadChain;
|
|
20707
21119
|
exports.waitForEntityIdle = waitForEntityIdle;
|
|
20708
21120
|
exports.withSeed = withSeed;
|
|
20709
21121
|
exports.writeProcessMachine = writeProcessMachine;
|
|
20710
|
-
//# sourceMappingURL=index-
|
|
21122
|
+
//# sourceMappingURL=index-CSNtEnbF.js.map
|