@seedprotocol/sdk 0.7.4-next.784.g879c6a3 → 0.7.4

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.
Files changed (120) hide show
  1. package/dist/{BasePathResolver-DxdS0wJ0.js → BasePathResolver-DrzGVH9L.js} +232 -40
  2. package/dist/BasePathResolver-DrzGVH9L.js.map +1 -0
  3. package/dist/{ClientManager-De-vKHGe.js → ClientManager-Dfu4jcgm.js} +583 -219
  4. package/dist/ClientManager-Dfu4jcgm.js.map +1 -0
  5. package/dist/{Item-cq9VcsAY.js → Item-BUUFuywT.js} +175 -306
  6. package/dist/Item-BUUFuywT.js.map +1 -0
  7. package/dist/{ModelProperty-DuuoFXaC.js → ModelProperty-B6cnRvIz.js} +38 -39
  8. package/dist/ModelProperty-B6cnRvIz.js.map +1 -0
  9. package/dist/{Schema-Dc5EA8Yb.js → Schema-Bf-jOLq0.js} +37 -36
  10. package/dist/{Schema-Dc5EA8Yb.js.map → Schema-Bf-jOLq0.js.map} +1 -1
  11. package/dist/{SchemaValidationService-DViJ056F.js → SchemaValidationService-BNYMacsx.js} +7 -8
  12. package/dist/{SchemaValidationService-DViJ056F.js.map → SchemaValidationService-BNYMacsx.js.map} +1 -1
  13. package/dist/{backfillMetadataPropertyIds-DacVthS5.js → backfillMetadataPropertyIds-C2-s_jUa.js} +4 -5
  14. package/dist/{backfillMetadataPropertyIds-DacVthS5.js.map → backfillMetadataPropertyIds-C2-s_jUa.js.map} +1 -1
  15. package/dist/{configurePlatform-DlZ23w7e.js → configurePlatform-BzfirKuM.js} +3 -4
  16. package/dist/{configurePlatform-DlZ23w7e.js.map → configurePlatform-BzfirKuM.js.map} +1 -1
  17. package/dist/{detachRowsBeforeDelete-YRSZY6dO.js → detachRowsBeforeDelete-B0Daoz9Z.js} +3 -4
  18. package/dist/{detachRowsBeforeDelete-YRSZY6dO.js.map → detachRowsBeforeDelete-B0Daoz9Z.js.map} +1 -1
  19. package/dist/{eas-D_6ptL_F.js → eas-Dq5Kx_Nd.js} +14 -32
  20. package/dist/eas-Dq5Kx_Nd.js.map +1 -0
  21. package/dist/{errors-Cl8rbtKR.js → errors-DdWbxb_n.js} +42 -39
  22. package/dist/errors-DdWbxb_n.js.map +1 -0
  23. package/dist/{getItem-BcmJcUZB.js → getItem-9bYSErSj.js} +4 -5
  24. package/dist/{getItem-BcmJcUZB.js.map → getItem-9bYSErSj.js.map} +1 -1
  25. package/dist/{getPublishPayload-C278kK9P.js → getPublishPayload-DPy-uMrR.js} +28 -29
  26. package/dist/getPublishPayload-DPy-uMrR.js.map +1 -0
  27. package/dist/{getPublishUploads-DJ1UPh7i.js → getPublishUploads-J-143iSV.js} +10 -11
  28. package/dist/{getPublishUploads-DJ1UPh7i.js.map → getPublishUploads-J-143iSV.js.map} +1 -1
  29. package/dist/{index-DAl9U4rn.js → index-7y2f_iQz.js} +2 -2
  30. package/dist/index-7y2f_iQz.js.map +1 -0
  31. package/dist/{index-CqnU-5i0.js → index-C61Rxy0F.js} +9 -10
  32. package/dist/index-C61Rxy0F.js.map +1 -0
  33. package/dist/{index.browser-J6QZ9smP.js → index.browser-C1pisOEa.js} +10 -10
  34. package/dist/{index.browser-J6QZ9smP.js.map → index.browser-C1pisOEa.js.map} +1 -1
  35. package/dist/{index.node-C9VB9NlX.js → index.node-BAlST8pD.js} +6 -6
  36. package/dist/{index.node-C9VB9NlX.js.map → index.node-BAlST8pD.js.map} +1 -1
  37. package/dist/main.js +27 -28
  38. package/dist/main.js.map +1 -1
  39. package/dist/node.js +12 -13
  40. package/dist/node.js.map +1 -1
  41. package/dist/platform.browser.js +6 -7
  42. package/dist/platform.browser.js.map +1 -1
  43. package/dist/platform.node.js +5 -6
  44. package/dist/platform.node.js.map +1 -1
  45. package/dist/{property-Brgr5RdT.js → property-zFPMtR3T.js} +10 -14
  46. package/dist/property-zFPMtR3T.js.map +1 -0
  47. package/dist/{propertyValidationRules-CDRitiiK.js → propertyValidationRules-CeFVhdQg.js} +10 -10
  48. package/dist/{propertyValidationRules-CDRitiiK.js.map → propertyValidationRules-CeFVhdQg.js.map} +1 -1
  49. package/dist/{publishDraftGraph-C37ibxb5.js → publishDraftGraph-CuVq6iAR.js} +7 -6
  50. package/dist/{publishDraftGraph-C37ibxb5.js.map → publishDraftGraph-CuVq6iAR.js.map} +1 -1
  51. package/dist/{resetAmbiguousLegacyItemData-CcLFRREE.js → resetAmbiguousLegacyItemData-DsFTnMBz.js} +5 -6
  52. package/dist/resetAmbiguousLegacyItemData-DsFTnMBz.js.map +1 -0
  53. package/dist/{resolveModelForSyncedSeed-BTAeCOJE.js → resolveModelForSyncedSeed-RUsgAZXG.js} +2 -2
  54. package/dist/{resolveModelForSyncedSeed-BTAeCOJE.js.map → resolveModelForSyncedSeed-RUsgAZXG.js.map} +1 -1
  55. package/dist/src/Item/Item.d.ts.map +1 -1
  56. package/dist/src/ItemProperty/service/propertyMachine.d.ts +4 -4
  57. package/dist/src/Model/Model.d.ts +3 -2
  58. package/dist/src/Model/Model.d.ts.map +1 -1
  59. package/dist/src/ModelProperty/ModelProperty.d.ts +1 -1
  60. package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts +1 -1
  61. package/dist/src/Schema/service/schemaMachine.d.ts +2 -2
  62. package/dist/src/client/ClientManager.d.ts +6 -6
  63. package/dist/src/client/ClientManager.d.ts.map +1 -1
  64. package/dist/src/client/actors/addModelsToDb.d.ts.map +1 -1
  65. package/dist/src/client/actors/saveConfig.d.ts.map +1 -1
  66. package/dist/src/client/clientManagerMachine.d.ts +2 -2
  67. package/dist/src/client/clientManagerMachine.d.ts.map +1 -1
  68. package/dist/src/db/canonicalizeModelTypes.d.ts +18 -0
  69. package/dist/src/db/canonicalizeModelTypes.d.ts.map +1 -0
  70. package/dist/src/db/read/getModelSchemas.d.ts +6 -0
  71. package/dist/src/db/read/getModelSchemas.d.ts.map +1 -1
  72. package/dist/src/db/read/getPublishPayload.d.ts.map +1 -1
  73. package/dist/src/db/read/getSchemaUidForModel.d.ts +6 -0
  74. package/dist/src/db/read/getSchemaUidForModel.d.ts.map +1 -1
  75. package/dist/src/db/read/resolveModelRecord.d.ts.map +1 -1
  76. package/dist/src/db/removeForeignAttestationRows.d.ts +27 -0
  77. package/dist/src/db/removeForeignAttestationRows.d.ts.map +1 -0
  78. package/dist/src/db/write/createMetadata.d.ts.map +1 -1
  79. package/dist/src/db/write/easSyncProcess.d.ts +9 -1
  80. package/dist/src/db/write/easSyncProcess.d.ts.map +1 -1
  81. package/dist/src/db/write/updateMetadata.d.ts.map +1 -1
  82. package/dist/src/eas.d.ts.map +1 -1
  83. package/dist/src/events/item/easSyncManager.d.ts.map +1 -1
  84. package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
  85. package/dist/src/helpers/db.d.ts +20 -0
  86. package/dist/src/helpers/db.d.ts.map +1 -1
  87. package/dist/src/helpers/index.d.ts +3 -1
  88. package/dist/src/helpers/index.d.ts.map +1 -1
  89. package/dist/src/helpers/metadataPropertyNames.d.ts +12 -0
  90. package/dist/src/helpers/metadataPropertyNames.d.ts.map +1 -1
  91. package/dist/src/helpers/retryWhenOnline.d.ts +20 -0
  92. package/dist/src/helpers/retryWhenOnline.d.ts.map +1 -0
  93. package/dist/src/imports/json.d.ts +10 -0
  94. package/dist/src/imports/json.d.ts.map +1 -1
  95. package/dist/src/index.d.ts +4 -2
  96. package/dist/src/index.d.ts.map +1 -1
  97. package/dist/src/query/createLocalQueryDataSource.d.ts.map +1 -1
  98. package/dist/src/types/import.d.ts +4 -0
  99. package/dist/src/types/import.d.ts.map +1 -1
  100. package/dist/{syncDbWithEas-B-Ho0IOB.js → syncDbWithEas-CRpnkq00.js} +157 -61
  101. package/dist/syncDbWithEas-CRpnkq00.js.map +1 -0
  102. package/dist/{tabEvents-BTzckWrN.js → tabEvents-nBUq_1u1.js} +6 -6
  103. package/dist/{tabEvents-BTzckWrN.js.map → tabEvents-nBUq_1u1.js.map} +1 -1
  104. package/dist/{tolerantWebAccess-DOm2Xv-f.js → tolerantWebAccess-DIt3R8_u.js} +7 -8
  105. package/dist/{tolerantWebAccess-DOm2Xv-f.js.map → tolerantWebAccess-DIt3R8_u.js.map} +1 -1
  106. package/dist/{updateSeedRevokedAt-IHXnJI-i.js → updateSeedRevokedAt-DtTPSzpM.js} +3 -3
  107. package/dist/{updateSeedRevokedAt-IHXnJI-i.js.map → updateSeedRevokedAt-DtTPSzpM.js.map} +1 -1
  108. package/package.json +5 -5
  109. package/dist/BasePathResolver-DxdS0wJ0.js.map +0 -1
  110. package/dist/ClientManager-De-vKHGe.js.map +0 -1
  111. package/dist/Item-cq9VcsAY.js.map +0 -1
  112. package/dist/ModelProperty-DuuoFXaC.js.map +0 -1
  113. package/dist/eas-D_6ptL_F.js.map +0 -1
  114. package/dist/errors-Cl8rbtKR.js.map +0 -1
  115. package/dist/getPublishPayload-C278kK9P.js.map +0 -1
  116. package/dist/index-CqnU-5i0.js.map +0 -1
  117. package/dist/index-DAl9U4rn.js.map +0 -1
  118. package/dist/property-Brgr5RdT.js.map +0 -1
  119. package/dist/resetAmbiguousLegacyItemData-CcLFRREE.js.map +0 -1
  120. package/dist/syncDbWithEas-B-Ho0IOB.js.map +0 -1
@@ -1,19 +1,18 @@
1
1
  import debug from 'debug';
2
2
  import { isEasAttestationExplorerUrl, BaseArweaveClient, ensureReadGatewaySelected, getArweaveReadBaseUrls, getTransactionTagsByIds } from '@seedprotocol/arweave';
3
- import { BaseQueryClient, BaseEasClient, GET_FILES_METADATA } from '@seedprotocol/eas';
3
+ import { easName, localNamesInBestMatchTier, BaseQueryClient, BaseEasClient, GET_FILES_METADATA } from '@seedprotocol/eas';
4
4
  import { waitFor } from 'xstate';
5
- import 'pluralize';
5
+ import pluralize from 'pluralize';
6
6
  import { Type } from '@sinclair/typebox';
7
7
  import { sqliteTable, integer, text, unique, int, blob, uniqueIndex } from 'drizzle-orm/sqlite-core';
8
8
  import { relations, and, eq, inArray, desc, isNull, isNotNull, or } from 'drizzle-orm';
9
- import { toSnakeCase as toSnakeCase$1 } from 'drizzle-orm/casing';
10
- import { upperFirst, camelCase, throttle } from 'lodash-es';
11
9
  import { customAlphabet } from 'nanoid';
12
10
  import { alphanumeric } from 'nanoid-dictionary';
13
11
  import '@seedprotocol/query';
14
12
  import { sha256 } from '@noble/hashes/sha256';
15
13
  import { sha3_256 } from '@noble/hashes/sha3';
16
14
  import { bytesToHex } from '@noble/hashes/utils';
15
+ import { throttle } from 'lodash-es';
17
16
 
18
17
  class BaseDb {
19
18
  static configure(impl) {
@@ -468,6 +467,171 @@ const Property = {
468
467
  /** `Html` opts are not representable in `TPropertyConstructor`; keep runtime shape via double assert. */
469
468
  };
470
469
 
470
+ /** Ref model name when propDef is a List of Relation, else undefined. */
471
+ function listRelationRef(propDef) {
472
+ if (!propDef)
473
+ return undefined;
474
+ if (normalizeDataType(propDef.dataType) !== 'List')
475
+ return undefined;
476
+ return propDef.ref || propDef.refModelName || undefined;
477
+ }
478
+ /**
479
+ * Storage/EAS name for a List-of-relation property (`authorIdentityIds`), given either its
480
+ * schema key (`authors`) or its storage name. A name already in storage form is returned as-is,
481
+ * so this is safe on ItemProperties built before their schema was known.
482
+ * Returns undefined when propDef is not a List of Relation.
483
+ */
484
+ function listRelationEasPropertyName(propertyName, propDef) {
485
+ const ref = listRelationRef(propDef);
486
+ if (!ref || !propertyName)
487
+ return undefined;
488
+ if (propertyName.endsWith(`${ref}Ids`))
489
+ return propertyName;
490
+ return `${pluralize(propertyName, 1)}${ref}Ids`;
491
+ }
492
+ /**
493
+ * For a schema property key like `authors` (List of Relation to Identity), returns the
494
+ * internal storage/EAS name: `authorIdentityIds` (singular + ref + Ids).
495
+ */
496
+ function listRelationStoragePropertyName(propertySchemas, schemaPropertyKey) {
497
+ return listRelationEasPropertyName(schemaPropertyKey, propertySchemas[schemaPropertyKey]);
498
+ }
499
+ /**
500
+ * Reverse of listRelationStoragePropertyName: maps DB/EAS name `authorIdentityIds` to schema key `authors`.
501
+ */
502
+ function resolveStorageNameToSchemaName(propertySchemas, storagePropertyName) {
503
+ for (const [schemaKey, propDef] of Object.entries(propertySchemas)) {
504
+ if (normalizeDataType(propDef?.dataType) !== 'List')
505
+ continue;
506
+ const ref = propDef.ref || propDef.refModelName;
507
+ if (!ref)
508
+ continue;
509
+ const internalName = `${pluralize(schemaKey, 1)}${ref}Ids`;
510
+ if (internalName === storagePropertyName) {
511
+ return schemaKey;
512
+ }
513
+ }
514
+ return undefined;
515
+ }
516
+ /** Internal property names that never use Id-suffix metadata convention */
517
+ const ID_SUFFIX_EXCLUDE = new Set(['storageTransactionId', 'transactionId']);
518
+ /** Data types that store metadata with Id suffix in DB */
519
+ const METADATA_ID_SUFFIX_TYPES = ['Image', 'File', 'Html', 'Relation'];
520
+ /**
521
+ * Whether this type uses Id suffix in metadata table.
522
+ */
523
+ function needsMetadataIdSuffix(dataType, refValueType) {
524
+ const dt = normalizeDataType(dataType);
525
+ const rvt = normalizeDataType(refValueType);
526
+ return (METADATA_ID_SUFFIX_TYPES.includes(dt) ||
527
+ METADATA_ID_SUFFIX_TYPES.includes(rvt));
528
+ }
529
+ /**
530
+ * Canonical metadata property name for WRITES.
531
+ * Use when creating/updating metadata.
532
+ */
533
+ function toMetadataPropertyName(propertyName, dataType, refValueType) {
534
+ if (ID_SUFFIX_EXCLUDE.has(propertyName))
535
+ return propertyName;
536
+ if (propertyName.endsWith('Ids'))
537
+ return propertyName;
538
+ if (propertyName.endsWith('Id'))
539
+ return propertyName;
540
+ if (needsMetadataIdSuffix(dataType, refValueType)) {
541
+ return `${propertyName}Id`;
542
+ }
543
+ return propertyName;
544
+ }
545
+ /**
546
+ * For READS: property names to include in OR query (both variants).
547
+ * When dataType is undefined, includes all variants for safety (backwards compat with getPropertyData).
548
+ */
549
+ function getMetadataPropertyNamesForQuery(propertyName, dataType, refValueType) {
550
+ if (ID_SUFFIX_EXCLUDE.has(propertyName))
551
+ return [propertyName];
552
+ if (propertyName.endsWith('Ids'))
553
+ return [propertyName];
554
+ if (propertyName.endsWith('Id')) {
555
+ const base = propertyName.slice(0, -2);
556
+ return [propertyName, base];
557
+ }
558
+ const needsId = needsMetadataIdSuffix(dataType, refValueType) ||
559
+ (dataType === undefined && refValueType === undefined);
560
+ if (needsId) {
561
+ return [propertyName, `${propertyName}Id`, `${propertyName}Ids`];
562
+ }
563
+ return [propertyName];
564
+ }
565
+ /**
566
+ * Schema property name from metadata name (strip Id/Ids suffix).
567
+ */
568
+ function toSchemaPropertyName(propertyName) {
569
+ if (propertyName.endsWith('Ids'))
570
+ return propertyName.slice(0, -3);
571
+ if (propertyName.endsWith('Id'))
572
+ return propertyName.slice(0, -2);
573
+ return undefined;
574
+ }
575
+ /**
576
+ * Alternate property name for instance lookup (base <-> Id variant).
577
+ */
578
+ function getAlternatePropertyNameForInstanceLookup(propertyName) {
579
+ if (ID_SUFFIX_EXCLUDE.has(propertyName))
580
+ return undefined;
581
+ if (propertyName.endsWith('Id'))
582
+ return propertyName.slice(0, -2);
583
+ return `${propertyName}Id`;
584
+ }
585
+ /**
586
+ * Resolve the best metadata record when multiple variants exist (base + Id).
587
+ * For Image/File/Html: prefer the record with refResolvedValue (Id variant has filename).
588
+ */
589
+ function resolveMetadataRecord(records, preferredPropertyName, dataType, refValueType) {
590
+ if (records.length === 0)
591
+ throw new Error('No records to resolve');
592
+ if (records.length === 1)
593
+ return records[0];
594
+ const needsId = needsMetadataIdSuffix(dataType, refValueType) ||
595
+ (dataType === undefined && refValueType === undefined);
596
+ // For Image/File/Html: prefer the record with refResolvedValue (Id variant has filename)
597
+ if (needsId) {
598
+ const withRef = records.find((r) => r.refResolvedValue);
599
+ if (withRef)
600
+ return withRef;
601
+ }
602
+ // Also prefer by refSeedType when we need file ref
603
+ if (needsId) {
604
+ const byRefSeed = records.find((r) => r.refSeedType === 'image' ||
605
+ r.refSeedType === 'file' ||
606
+ r.refSeedType === 'html');
607
+ if (byRefSeed)
608
+ return byRefSeed;
609
+ }
610
+ // Fallback: prefer exact propertyName match, else first
611
+ return (records.find((r) => r.propertyName === preferredPropertyName) ?? records[0]);
612
+ }
613
+ /**
614
+ * The EAS property name publish writes for an item property (ADR 0008 §3), already in EAS form:
615
+ *
616
+ * - List of relations: its `<name><Model>Ids` storage name (`author_identity_ids`).
617
+ * - Single Relation, Image, File or Html: its schema key (`author`), never the local `<name>Id`
618
+ * storage name. The key is `propertyDef.name` when known, else `propertyName` without its `Id`.
619
+ * - Anything else: the property name.
620
+ */
621
+ function easPropertyNameForPublish(propertyName, propertyDef) {
622
+ const listRelationName = listRelationEasPropertyName(propertyName, propertyDef ?? undefined);
623
+ if (listRelationName)
624
+ return easName(listRelationName);
625
+ if (propertyDef &&
626
+ normalizeDataType(propertyDef.dataType) !== 'List' &&
627
+ needsMetadataIdSuffix(propertyDef.dataType, propertyDef.refValueType) &&
628
+ !ID_SUFFIX_EXCLUDE.has(propertyName)) {
629
+ const key = propertyDef.name ?? (propertyName.endsWith('Id') ? propertyName.slice(0, -2) : propertyName);
630
+ return easName(key);
631
+ }
632
+ return easName(propertyName);
633
+ }
634
+
471
635
  /** Same rules as getCorrectId in helpers/index (avoid barrel circular import). */
472
636
  function parseLocalIdOrUid(localIdOrUid) {
473
637
  const id = { localId: undefined, uid: undefined };
@@ -1224,16 +1388,16 @@ const resolveModelRecordByNameOnly = async (modelName, db, label = Array.isArray
1224
1388
  return { id: chosen.id, name: chosen.name, schemaFileId: chosen.schemaFileId };
1225
1389
  };
1226
1390
  /**
1227
- * The model names a model name or EAS model type can refer to: the name itself, names whose
1228
- * snake_case form is the type (`new_model` → "New model", as Model.findByModelType matches), and
1229
- * the PascalCase form older callers relied on (`sync_storage_post` → "SyncStoragePost").
1391
+ * The model names a model name or EAS model type can refer to: the name itself, else the names
1392
+ * that match it in the tightest tier (ADR 0008, as Model.findByModelType matches): `new_model` →
1393
+ * "New model", `sync_storage_post` → "SyncStoragePost", `htmlpage` → "HTMLPage".
1230
1394
  */
1231
1395
  const modelNamesForNameOrType = async (nameOrType, db) => {
1232
- const pascal = upperFirst(camelCase(nameOrType));
1233
1396
  const rows = (await db.selectDistinct({ name: models.name }).from(models));
1234
- return rows
1235
- .map((r) => r.name)
1236
- .filter((name) => name === nameOrType || name === pascal || toSnakeCase$1(name) === nameOrType);
1397
+ const names = rows.map((r) => r.name);
1398
+ if (names.includes(nameOrType))
1399
+ return [nameOrType];
1400
+ return [...localNamesInBestMatchTier(nameOrType, names)];
1237
1401
  };
1238
1402
  /**
1239
1403
  * resolveModelRecord for a model name **or** an EAS model type (snake_case model name, what sync
@@ -1580,7 +1744,7 @@ async function migrateMetadataForPropertyRename(modelName, oldPropertyName, newP
1580
1744
  .where(eq(metadata.propertyId, propertyId));
1581
1745
  }
1582
1746
  // Fallback: update metadata with null propertyId (legacy rows) by propertyName + modelType
1583
- const modelType = toSnakeCase$1(modelName);
1747
+ const modelType = easName(modelName);
1584
1748
  const toUpdateByFallback = await db
1585
1749
  .select({ localId: metadata.localId })
1586
1750
  .from(metadata)
@@ -1601,6 +1765,45 @@ async function migrateMetadataForPropertyRename(modelName, oldPropertyName, newP
1601
1765
  }
1602
1766
  return total;
1603
1767
  }
1768
+ /**
1769
+ * Moves a renamed property's metadata rows to its new name: rows linked by propertyId, and legacy
1770
+ * rows without one by name and model type. Each stored form of the name moves to the same form of
1771
+ * the new one: the key (`author` → `writer`), a single relation's `<key>Id` (`authorId` →
1772
+ * `writerId`), a list relation's storage name (`authorIdentityIds` → `writerIdentityIds`).
1773
+ * Returns the number of rows moved.
1774
+ */
1775
+ async function moveMetadataToRenamedProperty(db, { propertyId, modelType, oldName, newName, propertyDef, }) {
1776
+ const forms = (name) => [
1777
+ name,
1778
+ toMetadataPropertyName(name, propertyDef?.dataType, propertyDef?.refValueType),
1779
+ listRelationEasPropertyName(name, propertyDef) ?? name,
1780
+ ];
1781
+ const oldForms = forms(oldName);
1782
+ const newForms = forms(newName);
1783
+ let moved = 0;
1784
+ const seen = new Set();
1785
+ for (let i = 0; i < oldForms.length; i++) {
1786
+ const from = oldForms[i];
1787
+ const to = newForms[i];
1788
+ if (from === to || seen.has(from))
1789
+ continue;
1790
+ seen.add(from);
1791
+ const byId = await db
1792
+ .update(metadata)
1793
+ .set({ propertyName: to })
1794
+ .where(and(eq(metadata.propertyId, propertyId), eq(metadata.propertyName, from)))
1795
+ .returning({ localId: metadata.localId });
1796
+ const legacy = await db
1797
+ .update(metadata)
1798
+ .set({ propertyName: to })
1799
+ .where(and(isNull(metadata.propertyId), eq(metadata.propertyName, from), eq(metadata.modelType, modelType)))
1800
+ .returning({ localId: metadata.localId });
1801
+ moved += byId.length + legacy.length;
1802
+ }
1803
+ if (moved > 0)
1804
+ logger$3(`[moveMetadataToRenamedProperty] moved ${moved} metadata rows ${oldName} -> ${newName}`);
1805
+ return moved;
1806
+ }
1604
1807
  const getObjectForRow = (row) => {
1605
1808
  const obj = {};
1606
1809
  row.columnNames.forEach((colName, index) => {
@@ -2504,27 +2707,8 @@ const addModelsToDb = async (models$1, schema, modelRenames, schemaFileData) =>
2504
2707
  // If refValueType is not set, ensure it's null
2505
2708
  propertyData.refValueType = null;
2506
2709
  }
2507
- // If not found by name, try to find by position/characteristics (for renamed properties)
2508
- if (!existingProperty) {
2509
- // Look for unmatched DB properties that could be this renamed property
2510
- // Match by: same dataType, same refModelId (if applicable), and not matching any schema property name
2511
- const potentialMatches = allDbProperties.filter((p) => !matchedDbPropertyIds.has(p.id) &&
2512
- !schemaPropertyNames.has(p.name) && // This DB property doesn't match any schema property name
2513
- p.dataType === propertyValues.dataType &&
2514
- (expectedRefModelId === null
2515
- ? p.refModelId === null
2516
- : p.refModelId === expectedRefModelId) &&
2517
- (propertyValues.refValueType
2518
- ? p.refValueType === propertyValues.refValueType
2519
- : p.refValueType === null));
2520
- // If we find exactly one match, or if we're at the same position index, use it
2521
- // For now, use the first match (could be enhanced to use position more precisely)
2522
- if (potentialMatches.length > 0) {
2523
- const matchedProperty = potentialMatches[0];
2524
- existingProperty = matchedProperty;
2525
- logger$3(`Found renamed property: ${modelName}:${matchedProperty.name} -> ${propertyName} (matched by characteristics)`);
2526
- }
2527
- }
2710
+ // ADR 0008: a rename needs the property's id. A name that matches no stored property by id
2711
+ // or name is a new property, even if one of the same type was removed in the same edit.
2528
2712
  if (existingProperty) {
2529
2713
  // Mark this DB property as matched
2530
2714
  matchedDbPropertyIds.add(existingProperty.id);
@@ -2582,6 +2766,16 @@ const addModelsToDb = async (models$1, schema, modelRenames, schemaFileData) =>
2582
2766
  if (updatedFileId)
2583
2767
  updatedPropertyFileIds.push(updatedFileId);
2584
2768
  }
2769
+ if (existingProperty.name !== propertyName) {
2770
+ // Renamed (matched by id): its values move to the new name.
2771
+ await moveMetadataToRenamedProperty(db, {
2772
+ propertyId: existingProperty.id,
2773
+ modelType: easName(modelName),
2774
+ oldName: existingProperty.name,
2775
+ newName: propertyName,
2776
+ propertyDef: propertyValues,
2777
+ });
2778
+ }
2585
2779
  }
2586
2780
  else {
2587
2781
  // Property doesn't exist, create it with schemaFileId
@@ -3524,6 +3718,7 @@ var db = /*#__PURE__*/Object.freeze({
3524
3718
  getWatchedAddressesFromDb: getWatchedAddressesFromDb,
3525
3719
  loadModelsFromDbForSchema: loadModelsFromDbForSchema,
3526
3720
  migrateMetadataForPropertyRename: migrateMetadataForPropertyRename,
3721
+ moveMetadataToRenamedProperty: moveMetadataToRenamedProperty,
3527
3722
  propertyStorageColumns: propertyStorageColumns,
3528
3723
  renameModelInDb: renameModelInDb,
3529
3724
  savePropertyToDb: savePropertyToDb,
@@ -3743,8 +3938,8 @@ const syncDbFiles = async (endpoints) => {
3743
3938
  const getAppDbReady = async () => {
3744
3939
  if (!BaseDb.isAppDbReady()) {
3745
3940
  // Wait for ClientManager to be ready (DB_INIT state or later)
3746
- const _mod_0 = await import('./ClientManager-De-vKHGe.js');
3747
- const _ns_0 = _mod_0.L;
3941
+ const _mod_0 = await import('./ClientManager-Dfu4jcgm.js');
3942
+ const _ns_0 = _mod_0.M;
3748
3943
  const clientManagerMod = _ns_0;
3749
3944
  const { getClient } = clientManagerMod;
3750
3945
  const clientManager = getClient();
@@ -4487,9 +4682,6 @@ var generateId$1 = /*#__PURE__*/Object.freeze({
4487
4682
  });
4488
4683
 
4489
4684
  const logger = debug('seedSdk:shared:helpers');
4490
- const toSnakeCase = (str) => {
4491
- return str.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
4492
- };
4493
4685
  const getMimeType = (base64) => {
4494
4686
  if (!base64) {
4495
4687
  return null;
@@ -4639,5 +4831,5 @@ class BasePathResolver {
4639
4831
  }
4640
4832
  BasePathResolver._impl = null;
4641
4833
 
4642
- export { generateId as $, seeds as A, uploadProcesses as B, versions as C, DEFAULT_TEXT_MAX_LENGTH as D, BaseDb as E, AmbiguousModelError as F, eventEmitter as G, toSnakeCase as H, BasePathResolver as I, BaseFileManager as J, getPropertyIdForModelAndName as K, resolveItemModelFileId as L, ModelPropertyDataTypes as M, resolveSeedIdsFromRefString as N, normalizeRelationPropertyValue as O, Property as P, isPublishedSeedRef as Q, getStorageDirForDataType as R, getContentSha256 as S, THtmlEmbeddedDataUriPolicy as T, buildArweaveContentTags as U, getItemStorageSubdir as V, getItemStorageLocalFileName as W, normalizePublisher as X, getAllAddressesFromDb as Y, scheduleBulkFilesDownloadFromEasSync as Z, EAS_SEED_DATA_SYNCED_TO_DB_EVENT as _, TProperty as a, BaseFileManager$1 as a$, normalizeHexAddress as a0, getItemStoragePropertiesForModel as a1, addModelsToDb as a2, INIT_SCRIPT_SUCCESS_MESSAGE as a3, SCHEMA_TS as a4, getCorrectId as a5, SEED_CONFIG_FILE as a6, SEED_CONFIG_FALLBACKS as a7, isNode as a8, ZERO_BYTES32 as a9, normalizeAddressConfig as aA, normalizeAddressList as aB, normalizeArweaveTxIdForEnsure as aC, normalizeFeedItemFields as aD, resolveMediaRef as aE, isInternalSchema as aF, writeModelToDb as aG, writePropertyToDb as aH, addSchemaToDb as aI, renameModelInDb as aJ, loadModelsFromDbForSchema as aK, downloadAllFilesRequestHandler as aL, downloadAllFilesBinaryRequestHandler as aM, INTERNAL_SCHEMA_IDS as aN, linkModelToSchema as aO, getWatchedAddressesFromDb as aP, getOwnedAddressesFromDb as aQ, CLIENT_NOT_INITIALIZED as aR, getStorageTransactionIdForSeedUid as aS, convertTxIdToImage as aT, downloadTransactionIdWithDedupe as aU, getPropertyIdForSchemaFileId as aV, getDataTypeFromString as aW, getMimeType as aX, PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP as aY, BaseDb$1 as aZ, ModelSchema as a_, resolveModelRecord as aa, getItemModelScope as ab, VERSION_SCHEMA_UID as ac, INTERNAL_PROPERTY_NAMES as ad, isStorageSeedRef as ae, defaultAttestationData as af, INTERNAL_DATA_TYPES as ag, isBrowser as ah, getModelIdByFileId as ai, getModelId as aj, setCachedPropertyRefresher as ak, getArweaveUrlForTransaction as al, INTERNAL_STORAGE_MODEL_FILE_IDS as am, CONTENT_SHA256_TAG as an, CONTENT_TYPE_TAG as ao, ImageSize as ap, SEED_PROTOCOL_SCHEMA_NAME as aq, SeedModels as ar, VERSION_SCHEMA_DEF as as, VERSION_SCHEMA_UID_OPTIMISM_SEPOLIA as at, classifyMediaRef as au, closestImageSize as av, contentSha256TagMatches as aw, ensureImageLocal as ax, getAddressesForItemsFilter as ay, getFeedItemStringField as az, TPropertyConstructor as b, SchemaSchema as b0, ModelSchemaSchema as b1, resolveModelRecord$1 as b2, db as b3, download as b4, generateId$1 as b5, TPropertyDataType as c, TPropertyDefs as d, TStorageType as e, TValidationRules as f, normalizePropertyRecordSchema as g, appState as h, isDataType as i, arweaveL1FinalizeJobs as j, config as k, easSyncProcesses as l, metadata as m, normalizeDataType as n, htmlEmbeddedImageCoPublish as o, modelRelations as p, modelSchemas as q, modelUids as r, models as s, modelsRelations as t, properties as u, propertiesRelations as v, propertyUidRelations as w, propertyUids as x, publishProcesses as y, schemas as z };
4643
- //# sourceMappingURL=BasePathResolver-DxdS0wJ0.js.map
4834
+ export { generateId as $, seeds as A, uploadProcesses as B, versions as C, DEFAULT_TEXT_MAX_LENGTH as D, BaseDb as E, resolveStorageNameToSchemaName as F, AmbiguousModelError as G, eventEmitter as H, BasePathResolver as I, BaseFileManager as J, getPropertyIdForModelAndName as K, resolveItemModelFileId as L, ModelPropertyDataTypes as M, resolveSeedIdsFromRefString as N, normalizeRelationPropertyValue as O, Property as P, isPublishedSeedRef as Q, getStorageDirForDataType as R, getContentSha256 as S, THtmlEmbeddedDataUriPolicy as T, buildArweaveContentTags as U, getItemStorageSubdir as V, getItemStorageLocalFileName as W, normalizePublisher as X, getAllAddressesFromDb as Y, scheduleBulkFilesDownloadFromEasSync as Z, EAS_SEED_DATA_SYNCED_TO_DB_EVENT as _, TProperty as a, getPropertyIdForSchemaFileId as a$, normalizeHexAddress as a0, listRelationEasPropertyName as a1, easPropertyNameForPublish as a2, toMetadataPropertyName as a3, getItemStoragePropertiesForModel as a4, addModelsToDb as a5, INIT_SCRIPT_SUCCESS_MESSAGE as a6, SCHEMA_TS as a7, getCorrectId as a8, SEED_CONFIG_FILE as a9, ensureImageLocal as aA, getAddressesForItemsFilter as aB, getFeedItemStringField as aC, normalizeAddressConfig as aD, normalizeAddressList as aE, normalizeArweaveTxIdForEnsure as aF, normalizeFeedItemFields as aG, resolveMediaRef as aH, isInternalSchema as aI, writeModelToDb as aJ, writePropertyToDb as aK, addSchemaToDb as aL, renameModelInDb as aM, loadModelsFromDbForSchema as aN, downloadAllFilesRequestHandler as aO, downloadAllFilesBinaryRequestHandler as aP, INTERNAL_SCHEMA_IDS as aQ, linkModelToSchema as aR, getWatchedAddressesFromDb as aS, getOwnedAddressesFromDb as aT, CLIENT_NOT_INITIALIZED as aU, toSchemaPropertyName as aV, getStorageTransactionIdForSeedUid as aW, convertTxIdToImage as aX, getMetadataPropertyNamesForQuery as aY, downloadTransactionIdWithDedupe as aZ, resolveMetadataRecord as a_, SEED_CONFIG_FALLBACKS as aa, isNode as ab, ZERO_BYTES32 as ac, resolveModelRecord as ad, getItemModelScope as ae, VERSION_SCHEMA_UID as af, INTERNAL_PROPERTY_NAMES as ag, isStorageSeedRef as ah, defaultAttestationData as ai, INTERNAL_DATA_TYPES as aj, isBrowser as ak, getModelIdByFileId as al, getModelId as am, setCachedPropertyRefresher as an, getArweaveUrlForTransaction as ao, INTERNAL_STORAGE_MODEL_FILE_IDS as ap, CONTENT_SHA256_TAG as aq, CONTENT_TYPE_TAG as ar, ImageSize as as, SEED_PROTOCOL_SCHEMA_NAME as at, SeedModels as au, VERSION_SCHEMA_DEF as av, VERSION_SCHEMA_UID_OPTIMISM_SEPOLIA as aw, classifyMediaRef as ax, closestImageSize as ay, contentSha256TagMatches as az, TPropertyConstructor as b, getDataTypeFromString as b0, getMimeType as b1, listRelationStoragePropertyName as b2, PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP as b3, getAlternatePropertyNameForInstanceLookup as b4, BaseDb$1 as b5, ModelSchema as b6, BaseFileManager$1 as b7, SchemaSchema as b8, ModelSchemaSchema as b9, resolveModelRecord$1 as ba, db as bb, download as bc, generateId$1 as bd, TPropertyDataType as c, TPropertyDefs as d, TStorageType as e, TValidationRules as f, normalizePropertyRecordSchema as g, appState as h, isDataType as i, arweaveL1FinalizeJobs as j, config as k, easSyncProcesses as l, metadata as m, normalizeDataType as n, htmlEmbeddedImageCoPublish as o, modelRelations as p, modelSchemas as q, modelUids as r, models as s, modelsRelations as t, properties as u, propertiesRelations as v, propertyUidRelations as w, propertyUids as x, publishProcesses as y, schemas as z };
4835
+ //# sourceMappingURL=BasePathResolver-DrzGVH9L.js.map