@seedprotocol/sdk 0.7.4-next.793.g6dd83dd → 0.7.5-next.850.g9ab585b
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/README.md +99 -0
- package/dist/{BasePathResolver-DT63t0XU.js → BasePathResolver-CsZHPrk9.js} +366 -40
- package/dist/BasePathResolver-CsZHPrk9.js.map +1 -0
- package/dist/{ClientManager-Cos8NaRU.js → ClientManager-DETTj0_z.js} +311 -189
- package/dist/ClientManager-DETTj0_z.js.map +1 -0
- package/dist/{Item-CoP48bl3.js → Item-TMrVEPeX.js} +75 -219
- package/dist/Item-TMrVEPeX.js.map +1 -0
- package/dist/{ModelProperty-jSo2QWIc.js → ModelProperty-Bw6N8OMK.js} +37 -38
- package/dist/ModelProperty-Bw6N8OMK.js.map +1 -0
- package/dist/{Schema-DN1KwJ57.js → Schema-VLenyJDy.js} +57 -36
- package/dist/Schema-VLenyJDy.js.map +1 -0
- package/dist/{SchemaValidationService-CCG9Bu__.js → SchemaValidationService-CLGadxgf.js} +7 -8
- package/dist/{SchemaValidationService-CCG9Bu__.js.map → SchemaValidationService-CLGadxgf.js.map} +1 -1
- package/dist/{backfillMetadataPropertyIds-D8t61oNl.js → backfillMetadataPropertyIds-C8fSvzy2.js} +4 -5
- package/dist/{backfillMetadataPropertyIds-D8t61oNl.js.map → backfillMetadataPropertyIds-C8fSvzy2.js.map} +1 -1
- package/dist/{configurePlatform-Su9vV5qO.js → configurePlatform-C3E0BS3u.js} +3 -4
- package/dist/{configurePlatform-Su9vV5qO.js.map → configurePlatform-C3E0BS3u.js.map} +1 -1
- package/dist/{detachRowsBeforeDelete-DcWDZ8KP.js → detachRowsBeforeDelete-D1gTseFW.js} +3 -4
- package/dist/{detachRowsBeforeDelete-DcWDZ8KP.js.map → detachRowsBeforeDelete-D1gTseFW.js.map} +1 -1
- package/dist/{eas-Ce0KDpvb.js → eas-A82zVNQ9.js} +16 -21
- package/dist/eas-A82zVNQ9.js.map +1 -0
- package/dist/{errors-D1brJy1k.js → errors-CWKup8tw.js} +45 -39
- package/dist/errors-CWKup8tw.js.map +1 -0
- package/dist/{getItem-Cs5IIZCQ.js → getItem-ChieGxJV.js} +4 -5
- package/dist/{getItem-Cs5IIZCQ.js.map → getItem-ChieGxJV.js.map} +1 -1
- package/dist/{getPublishPayload-CquFaK1c.js → getPublishPayload-CWfjl8PM.js} +39 -30
- package/dist/getPublishPayload-CWfjl8PM.js.map +1 -0
- package/dist/{getPublishUploads-Bv9aOq2x.js → getPublishUploads-cLbSEXLk.js} +10 -11
- package/dist/{getPublishUploads-Bv9aOq2x.js.map → getPublishUploads-cLbSEXLk.js.map} +1 -1
- package/dist/{index-BPrJV9Wt.js → index-CURf9L4d.js} +2 -2
- package/dist/index-CURf9L4d.js.map +1 -0
- package/dist/{index-DhP5gMMF.js → index-CXkcz4hT.js} +9 -10
- package/dist/index-CXkcz4hT.js.map +1 -0
- package/dist/{index.browser-cpZehMwT.js → index.browser-47W0fJPw.js} +10 -10
- package/dist/{index.browser-cpZehMwT.js.map → index.browser-47W0fJPw.js.map} +1 -1
- package/dist/{index.node-D_-a9z-S.js → index.node-BiQhZQvH.js} +6 -6
- package/dist/{index.node-D_-a9z-S.js.map → index.node-BiQhZQvH.js.map} +1 -1
- package/dist/main.js +29 -28
- package/dist/main.js.map +1 -1
- package/dist/node.js +12 -13
- package/dist/node.js.map +1 -1
- package/dist/platform.browser.js +6 -7
- package/dist/platform.browser.js.map +1 -1
- package/dist/platform.node.js +5 -6
- package/dist/platform.node.js.map +1 -1
- package/dist/{property-DNfhGsdq.js → property-tgPI5hMu.js} +10 -14
- package/dist/property-tgPI5hMu.js.map +1 -0
- package/dist/{propertyValidationRules-BiEBQvPZ.js → propertyValidationRules-BLVxTejW.js} +10 -10
- package/dist/{propertyValidationRules-BiEBQvPZ.js.map → propertyValidationRules-BLVxTejW.js.map} +1 -1
- package/dist/{publishDraftGraph-BZ6gku_X.js → publishDraftGraph-FAfecR_4.js} +7 -6
- package/dist/{publishDraftGraph-BZ6gku_X.js.map → publishDraftGraph-FAfecR_4.js.map} +1 -1
- package/dist/{resetAmbiguousLegacyItemData-CkSoBEOU.js → resetAmbiguousLegacyItemData-kz2PYdZi.js} +5 -6
- package/dist/resetAmbiguousLegacyItemData-kz2PYdZi.js.map +1 -0
- package/dist/{resolveModelForSyncedSeed-CsnKV72V.js → resolveModelForSyncedSeed-Dm1E4ebt.js} +2 -2
- package/dist/{resolveModelForSyncedSeed-CsnKV72V.js.map → resolveModelForSyncedSeed-Dm1E4ebt.js.map} +1 -1
- package/dist/src/Item/Item.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/propertyMachine.d.ts +4 -4
- package/dist/src/Model/Model.d.ts +4 -2
- package/dist/src/Model/Model.d.ts.map +1 -1
- package/dist/src/ModelProperty/ModelProperty.d.ts +1 -1
- package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts +1 -1
- package/dist/src/Schema/Schema.d.ts.map +1 -1
- package/dist/src/Schema/service/schemaMachine.d.ts +5 -2
- package/dist/src/Schema/service/schemaMachine.d.ts.map +1 -1
- package/dist/src/client/ClientManager.d.ts +6 -6
- package/dist/src/client/clientManagerMachine.d.ts +2 -2
- package/dist/src/client/clientManagerMachine.d.ts.map +1 -1
- package/dist/src/db/canonicalizeModelTypes.d.ts +18 -0
- package/dist/src/db/canonicalizeModelTypes.d.ts.map +1 -0
- package/dist/src/db/read/getModelSchemas.d.ts +7 -0
- package/dist/src/db/read/getModelSchemas.d.ts.map +1 -1
- package/dist/src/db/read/getPublishPayload.d.ts.map +1 -1
- package/dist/src/db/read/nameMatchLevels.d.ts +64 -0
- package/dist/src/db/read/nameMatchLevels.d.ts.map +1 -0
- package/dist/src/db/read/resolveModelRecord.d.ts.map +1 -1
- package/dist/src/db/read/summarizePublishWork.d.ts +2 -0
- package/dist/src/db/read/summarizePublishWork.d.ts.map +1 -1
- package/dist/src/db/write/createMetadata.d.ts.map +1 -1
- package/dist/src/db/write/updateMetadata.d.ts.map +1 -1
- package/dist/src/eas.d.ts.map +1 -1
- package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
- package/dist/src/helpers/constants.d.ts.map +1 -1
- package/dist/src/helpers/db.d.ts +20 -0
- package/dist/src/helpers/db.d.ts.map +1 -1
- package/dist/src/helpers/easValueTypes.d.ts +16 -0
- package/dist/src/helpers/easValueTypes.d.ts.map +1 -0
- package/dist/src/helpers/index.d.ts +3 -1
- package/dist/src/helpers/index.d.ts.map +1 -1
- package/dist/src/helpers/metadataPropertyNames.d.ts +12 -0
- package/dist/src/helpers/metadataPropertyNames.d.ts.map +1 -1
- package/dist/src/imports/index.d.ts +1 -1
- package/dist/src/imports/index.d.ts.map +1 -1
- package/dist/src/imports/json.d.ts +10 -0
- package/dist/src/imports/json.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/query/createLocalQueryDataSource.d.ts.map +1 -1
- package/dist/src/types/import.d.ts +24 -0
- package/dist/src/types/import.d.ts.map +1 -1
- package/dist/{syncDbWithEas-CfRijZhj.js → syncDbWithEas-CMCAihFh.js} +230 -64
- package/dist/syncDbWithEas-CMCAihFh.js.map +1 -0
- package/dist/{tabEvents-D5X2Hwcp.js → tabEvents-BEAmMncP.js} +6 -6
- package/dist/{tabEvents-D5X2Hwcp.js.map → tabEvents-BEAmMncP.js.map} +1 -1
- package/dist/{tolerantWebAccess-BNYRvW9a.js → tolerantWebAccess-CqiDGEyR.js} +7 -8
- package/dist/{tolerantWebAccess-BNYRvW9a.js.map → tolerantWebAccess-CqiDGEyR.js.map} +1 -1
- package/dist/{updateSeedRevokedAt-B-xAQxaj.js → updateSeedRevokedAt-Bw3uEStt.js} +3 -3
- package/dist/{updateSeedRevokedAt-B-xAQxaj.js.map → updateSeedRevokedAt-Bw3uEStt.js.map} +1 -1
- package/package.json +9 -5
- package/dist/BasePathResolver-DT63t0XU.js.map +0 -1
- package/dist/ClientManager-Cos8NaRU.js.map +0 -1
- package/dist/Item-CoP48bl3.js.map +0 -1
- package/dist/ModelProperty-jSo2QWIc.js.map +0 -1
- package/dist/Schema-DN1KwJ57.js.map +0 -1
- package/dist/eas-Ce0KDpvb.js.map +0 -1
- package/dist/errors-D1brJy1k.js.map +0 -1
- package/dist/getPublishPayload-CquFaK1c.js.map +0 -1
- package/dist/index-BPrJV9Wt.js.map +0 -1
- package/dist/index-DhP5gMMF.js.map +0 -1
- package/dist/property-DNfhGsdq.js.map +0 -1
- package/dist/resetAmbiguousLegacyItemData-CkSoBEOU.js.map +0 -1
- package/dist/syncDbWithEas-CfRijZhj.js.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# @seedprotocol/sdk
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@seedprotocol/sdk)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://nodejs.org)
|
|
6
|
+
[](https://seedprotocol.io)
|
|
7
|
+
|
|
8
|
+
The official TypeScript SDK for [Seed Protocol](https://seedprotocol.io): a local-first, decentralized data layer.
|
|
9
|
+
|
|
10
|
+
**[→ Full documentation at seedprotocol.io](https://seedprotocol.io)**
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
- **Local-first ORM.** Define schemas, models and properties; the SDK stores items in SQLite and files in OPFS in the user's browser (or on disk in Node).
|
|
15
|
+
- **Decentralized sync.** Data is read from and published to the [Ethereum Attestation Service (EAS)](https://attest.sh) and [Arweave](https://www.arweave.org). There is no backend for you to run.
|
|
16
|
+
- **No custody.** User data lives on public infrastructure and in the user's browser, not on your servers.
|
|
17
|
+
|
|
18
|
+
Built and used by [PermaPress](https://permapress.xyz), the first client for Seed Protocol (by [JournoLabs](https://journolabs.xyz)).
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- **Node.js** `>= 20` and `<= 24`
|
|
23
|
+
- **Browser:** a modern browser with OPFS (e.g. Chromium-based, recent Firefox)
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @seedprotocol/sdk
|
|
29
|
+
# or
|
|
30
|
+
bun add @seedprotocol/sdk
|
|
31
|
+
# or
|
|
32
|
+
pnpm add @seedprotocol/sdk
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Browser apps built with Vite should also add [`@seedprotocol/vite`](https://www.npmjs.com/package/@seedprotocol/vite). For React hooks, add [`@seedprotocol/react`](https://www.npmjs.com/package/@seedprotocol/react).
|
|
36
|
+
|
|
37
|
+
## Quick start
|
|
38
|
+
|
|
39
|
+
Initialize the client once, then create schemas, models and items:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { client, Schema, Model } from '@seedprotocol/sdk'
|
|
43
|
+
|
|
44
|
+
await client.init({
|
|
45
|
+
config: {
|
|
46
|
+
filesDir: '.seed',
|
|
47
|
+
endpoints: { filePaths: '/files', files: '.seed' }, // optional on Node when filesDir is set
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const schema = await Schema.create('Blog')
|
|
52
|
+
|
|
53
|
+
const Post = await Model.create('Post', schema, {
|
|
54
|
+
properties: {
|
|
55
|
+
title: { dataType: 'Text' },
|
|
56
|
+
content: { dataType: 'Html' },
|
|
57
|
+
publishedAt: { dataType: 'Date' },
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const post = await Post.create({ title: 'Hello', content: '<p>First post</p>' })
|
|
62
|
+
|
|
63
|
+
// Update by assignment; the SDK persists the change.
|
|
64
|
+
post.title = 'Hello, world'
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
You can also declare your schema in a config file at the project root: `seed.config.ts` (recommended), `seed.schema.ts`, or `schema.ts`.
|
|
68
|
+
|
|
69
|
+
To publish items to EAS and Arweave, use [`@seedprotocol/publish`](https://www.npmjs.com/package/@seedprotocol/publish).
|
|
70
|
+
|
|
71
|
+
See the [Getting Started guide](https://github.com/JournoLabs/seed-protocol-sdk/blob/main/docs/GETTING_STARTED.md) for configuration, address sessions, property types, files and images.
|
|
72
|
+
|
|
73
|
+
## Entry points
|
|
74
|
+
|
|
75
|
+
| Import | Use |
|
|
76
|
+
| --- | --- |
|
|
77
|
+
| `@seedprotocol/sdk` | Main API: `client`, `Schema`, `Model`, `Item`, `ItemProperty`, query helpers |
|
|
78
|
+
| `@seedprotocol/sdk/node` | Node entry: `client`, `Item`, `FileManager`, `Db`, and `withSeed` for webpack configs |
|
|
79
|
+
| `@seedprotocol/sdk/platform` | Platform services: `configurePlatform`, `createPlatformServices` |
|
|
80
|
+
| `@seedprotocol/sdk/vite` | Re-export of `seedVitePlugin` from `@seedprotocol/vite` |
|
|
81
|
+
|
|
82
|
+
ESM is recommended. CommonJS also works: `const { Schema, Model, Item } = require('@seedprotocol/sdk')`.
|
|
83
|
+
|
|
84
|
+
## Related packages
|
|
85
|
+
|
|
86
|
+
| Package | Description |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| [`@seedprotocol/react`](https://www.npmjs.com/package/@seedprotocol/react) | React hooks and components |
|
|
89
|
+
| [`@seedprotocol/publish`](https://www.npmjs.com/package/@seedprotocol/publish) | Publish flow (EAS attestations + Arweave uploads) |
|
|
90
|
+
| [`@seedprotocol/vite`](https://www.npmjs.com/package/@seedprotocol/vite) | Vite plugin for browser apps |
|
|
91
|
+
| [`@seedprotocol/query`](https://www.npmjs.com/package/@seedprotocol/query) | Canonical Seed JSON queries over EAS or local SQLite |
|
|
92
|
+
| [`@seedprotocol/feed`](https://www.npmjs.com/package/@seedprotocol/feed) | RSS, Atom and JSON Feed generation |
|
|
93
|
+
| [`@seedprotocol/mapping`](https://www.npmjs.com/package/@seedprotocol/mapping) | Field mapping from external sources to models |
|
|
94
|
+
| [`@seedprotocol/eas`](https://www.npmjs.com/package/@seedprotocol/eas) | EAS GraphQL read client |
|
|
95
|
+
| [`@seedprotocol/arweave`](https://www.npmjs.com/package/@seedprotocol/arweave) | Arweave gateway client |
|
|
96
|
+
|
|
97
|
+
## License
|
|
98
|
+
|
|
99
|
+
MIT
|
|
@@ -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, DEFAULT_NAME_MATCH_LEVEL, compareNameMatchTiers, isNameMatchLevel, 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 };
|
|
@@ -1143,6 +1307,133 @@ function stackWithoutFrames(stack) {
|
|
|
1143
1307
|
.join('\n');
|
|
1144
1308
|
}
|
|
1145
1309
|
|
|
1310
|
+
const level = (value) => (isNameMatchLevel(value) ? value : undefined);
|
|
1311
|
+
const tighter = (a, b) => a === undefined || compareNameMatchTiers(b, a) < 0 ? b : a;
|
|
1312
|
+
/** The levels in one schema file for one of its models, or undefined when the file lacks the model. */
|
|
1313
|
+
const modelLevelsFromFile = (file, modelName) => {
|
|
1314
|
+
const modelDef = file.models?.[modelName];
|
|
1315
|
+
if (!modelDef)
|
|
1316
|
+
return undefined;
|
|
1317
|
+
const model = level(modelDef.nameMatch) ?? level(file.nameMatch) ?? DEFAULT_NAME_MATCH_LEVEL;
|
|
1318
|
+
const properties = new Map();
|
|
1319
|
+
for (const [propertyName, def] of Object.entries(modelDef.properties ?? {})) {
|
|
1320
|
+
properties.set(propertyName, level(def?.nameMatch) ?? model);
|
|
1321
|
+
}
|
|
1322
|
+
return { model, properties };
|
|
1323
|
+
};
|
|
1324
|
+
/**
|
|
1325
|
+
* Builds NameMatchLevels from the schema files that own each model row. Exported for tests;
|
|
1326
|
+
* use {@link nameMatchLevels}.
|
|
1327
|
+
*/
|
|
1328
|
+
const nameMatchLevelsFromRows = (rows) => {
|
|
1329
|
+
const byFileId = new Map();
|
|
1330
|
+
const byName = new Map();
|
|
1331
|
+
const parsed = new Map();
|
|
1332
|
+
for (const row of rows) {
|
|
1333
|
+
if (!row.schemaData)
|
|
1334
|
+
continue;
|
|
1335
|
+
if (!parsed.has(row.schemaData)) {
|
|
1336
|
+
try {
|
|
1337
|
+
parsed.set(row.schemaData, JSON.parse(row.schemaData));
|
|
1338
|
+
}
|
|
1339
|
+
catch {
|
|
1340
|
+
parsed.set(row.schemaData, undefined);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
const file = parsed.get(row.schemaData);
|
|
1344
|
+
const levels = file && modelLevelsFromFile(file, row.modelName);
|
|
1345
|
+
if (!levels)
|
|
1346
|
+
continue;
|
|
1347
|
+
if (row.modelFileId)
|
|
1348
|
+
byFileId.set(row.modelFileId, levels);
|
|
1349
|
+
const seen = byName.get(row.modelName);
|
|
1350
|
+
if (!seen) {
|
|
1351
|
+
byName.set(row.modelName, { model: levels.model, properties: new Map(levels.properties) });
|
|
1352
|
+
continue;
|
|
1353
|
+
}
|
|
1354
|
+
seen.model = tighter(seen.model, levels.model);
|
|
1355
|
+
for (const [name, value] of levels.properties)
|
|
1356
|
+
seen.properties.set(name, tighter(seen.properties.get(name), value));
|
|
1357
|
+
}
|
|
1358
|
+
return {
|
|
1359
|
+
model: (modelName) => byName.get(modelName)?.model ?? DEFAULT_NAME_MATCH_LEVEL,
|
|
1360
|
+
property: (modelName, propertyName, modelFileId) => {
|
|
1361
|
+
const levels = (modelFileId ? byFileId.get(modelFileId) : undefined) ?? byName.get(modelName);
|
|
1362
|
+
return levels?.properties.get(propertyName) ?? levels?.model ?? DEFAULT_NAME_MATCH_LEVEL;
|
|
1363
|
+
},
|
|
1364
|
+
};
|
|
1365
|
+
};
|
|
1366
|
+
const DEFAULT_LEVELS = {
|
|
1367
|
+
model: () => DEFAULT_NAME_MATCH_LEVEL,
|
|
1368
|
+
property: () => DEFAULT_NAME_MATCH_LEVEL,
|
|
1369
|
+
};
|
|
1370
|
+
let current;
|
|
1371
|
+
let loading;
|
|
1372
|
+
/** Reads the levels from the schema files stored with each model's schema row (schemas.schema_data). */
|
|
1373
|
+
const loadNameMatchLevels = async (db = BaseDb.getAppDb()) => {
|
|
1374
|
+
if (!db)
|
|
1375
|
+
return DEFAULT_LEVELS;
|
|
1376
|
+
const load = (async () => {
|
|
1377
|
+
const rows = (await db
|
|
1378
|
+
.select({ modelName: models.name, modelFileId: models.schemaFileId, schemaData: schemas.schemaData })
|
|
1379
|
+
.from(models)
|
|
1380
|
+
.innerJoin(modelSchemas, eq(models.id, modelSchemas.modelId))
|
|
1381
|
+
.innerJoin(schemas, eq(modelSchemas.schemaId, schemas.id)));
|
|
1382
|
+
return nameMatchLevelsFromRows(rows);
|
|
1383
|
+
})();
|
|
1384
|
+
loading = load;
|
|
1385
|
+
try {
|
|
1386
|
+
const levels = await load;
|
|
1387
|
+
if (loading === load)
|
|
1388
|
+
current = levels;
|
|
1389
|
+
return levels;
|
|
1390
|
+
}
|
|
1391
|
+
finally {
|
|
1392
|
+
if (loading === load)
|
|
1393
|
+
loading = undefined;
|
|
1394
|
+
}
|
|
1395
|
+
};
|
|
1396
|
+
/** The levels, loaded once and reused until a schema write clears them. */
|
|
1397
|
+
const nameMatchLevels = async (db = BaseDb.getAppDb()) => current ?? loading ?? loadNameMatchLevels(db);
|
|
1398
|
+
/**
|
|
1399
|
+
* The last loaded levels, for synchronous callers (Model.findByModelType). Sync and the post-init
|
|
1400
|
+
* model type pass load them; before that every name is at DEFAULT_NAME_MATCH_LEVEL.
|
|
1401
|
+
*/
|
|
1402
|
+
const currentNameMatchLevels = () => current ?? DEFAULT_LEVELS;
|
|
1403
|
+
/** Called when a schema row or its models are written, so the next read reloads. */
|
|
1404
|
+
const clearNameMatchLevels = () => {
|
|
1405
|
+
current = undefined;
|
|
1406
|
+
loading = undefined;
|
|
1407
|
+
};
|
|
1408
|
+
/**
|
|
1409
|
+
* `nameMatch` values in a schema file that aren't a level. They are ignored (the next level up
|
|
1410
|
+
* applies); schema loads warn about them.
|
|
1411
|
+
*/
|
|
1412
|
+
const invalidNameMatchValues = (file) => {
|
|
1413
|
+
const problems = [];
|
|
1414
|
+
const check = (where, value) => {
|
|
1415
|
+
if (value !== undefined && !isNameMatchLevel(value)) {
|
|
1416
|
+
problems.push(`${where} nameMatch ${JSON.stringify(value)} is not 'exact', 'normalized' or 'fuzzy'`);
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1419
|
+
check('schema', file.nameMatch);
|
|
1420
|
+
for (const [modelName, modelDef] of Object.entries(file.models ?? {})) {
|
|
1421
|
+
check(modelName, modelDef?.nameMatch);
|
|
1422
|
+
for (const [propertyName, def] of Object.entries(modelDef?.properties ?? {})) {
|
|
1423
|
+
check(`${modelName}.${propertyName}`, def?.nameMatch);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
return problems;
|
|
1427
|
+
};
|
|
1428
|
+
/** Warns about {@link invalidNameMatchValues}. */
|
|
1429
|
+
const warnOnInvalidNameMatch = (file) => {
|
|
1430
|
+
const problems = invalidNameMatchValues(file);
|
|
1431
|
+
for (const problem of problems) {
|
|
1432
|
+
console.warn(`[seed] schema ${file.metadata?.name ?? ''}: ${problem}; it is ignored.`);
|
|
1433
|
+
}
|
|
1434
|
+
return problems;
|
|
1435
|
+
};
|
|
1436
|
+
|
|
1146
1437
|
/**
|
|
1147
1438
|
* Thrown when a model name exists in more than one schema and nothing says which one is meant.
|
|
1148
1439
|
* Model names are only unique within a schema; pass `schemaName` (or `modelFileId`) to choose.
|
|
@@ -1224,16 +1515,18 @@ const resolveModelRecordByNameOnly = async (modelName, db, label = Array.isArray
|
|
|
1224
1515
|
return { id: chosen.id, name: chosen.name, schemaFileId: chosen.schemaFileId };
|
|
1225
1516
|
};
|
|
1226
1517
|
/**
|
|
1227
|
-
* The model names a model name or EAS model type can refer to: the name itself, names
|
|
1228
|
-
*
|
|
1229
|
-
*
|
|
1518
|
+
* The model names a model name or EAS model type can refer to: the name itself, else the names
|
|
1519
|
+
* that match it in the tightest tier (ADR 0008, as Model.findByModelType matches): `new_model` →
|
|
1520
|
+
* "New model", `sync_storage_post` → "SyncStoragePost", `htmlpage` → "HTMLPage". Each name at its
|
|
1521
|
+
* nameMatch level (ADR 0009).
|
|
1230
1522
|
*/
|
|
1231
1523
|
const modelNamesForNameOrType = async (nameOrType, db) => {
|
|
1232
|
-
const pascal = upperFirst(camelCase(nameOrType));
|
|
1233
1524
|
const rows = (await db.selectDistinct({ name: models.name }).from(models));
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1525
|
+
const names = rows.map((r) => r.name);
|
|
1526
|
+
if (names.includes(nameOrType))
|
|
1527
|
+
return [nameOrType];
|
|
1528
|
+
const levels = await nameMatchLevels(db);
|
|
1529
|
+
return [...localNamesInBestMatchTier(nameOrType, names, { level: (name) => levels.model(name) })];
|
|
1237
1530
|
};
|
|
1238
1531
|
/**
|
|
1239
1532
|
* resolveModelRecord for a model name **or** an EAS model type (snake_case model name, what sync
|
|
@@ -1580,7 +1873,7 @@ async function migrateMetadataForPropertyRename(modelName, oldPropertyName, newP
|
|
|
1580
1873
|
.where(eq(metadata.propertyId, propertyId));
|
|
1581
1874
|
}
|
|
1582
1875
|
// Fallback: update metadata with null propertyId (legacy rows) by propertyName + modelType
|
|
1583
|
-
const modelType =
|
|
1876
|
+
const modelType = easName(modelName);
|
|
1584
1877
|
const toUpdateByFallback = await db
|
|
1585
1878
|
.select({ localId: metadata.localId })
|
|
1586
1879
|
.from(metadata)
|
|
@@ -1601,6 +1894,45 @@ async function migrateMetadataForPropertyRename(modelName, oldPropertyName, newP
|
|
|
1601
1894
|
}
|
|
1602
1895
|
return total;
|
|
1603
1896
|
}
|
|
1897
|
+
/**
|
|
1898
|
+
* Moves a renamed property's metadata rows to its new name: rows linked by propertyId, and legacy
|
|
1899
|
+
* rows without one by name and model type. Each stored form of the name moves to the same form of
|
|
1900
|
+
* the new one: the key (`author` → `writer`), a single relation's `<key>Id` (`authorId` →
|
|
1901
|
+
* `writerId`), a list relation's storage name (`authorIdentityIds` → `writerIdentityIds`).
|
|
1902
|
+
* Returns the number of rows moved.
|
|
1903
|
+
*/
|
|
1904
|
+
async function moveMetadataToRenamedProperty(db, { propertyId, modelType, oldName, newName, propertyDef, }) {
|
|
1905
|
+
const forms = (name) => [
|
|
1906
|
+
name,
|
|
1907
|
+
toMetadataPropertyName(name, propertyDef?.dataType, propertyDef?.refValueType),
|
|
1908
|
+
listRelationEasPropertyName(name, propertyDef) ?? name,
|
|
1909
|
+
];
|
|
1910
|
+
const oldForms = forms(oldName);
|
|
1911
|
+
const newForms = forms(newName);
|
|
1912
|
+
let moved = 0;
|
|
1913
|
+
const seen = new Set();
|
|
1914
|
+
for (let i = 0; i < oldForms.length; i++) {
|
|
1915
|
+
const from = oldForms[i];
|
|
1916
|
+
const to = newForms[i];
|
|
1917
|
+
if (from === to || seen.has(from))
|
|
1918
|
+
continue;
|
|
1919
|
+
seen.add(from);
|
|
1920
|
+
const byId = await db
|
|
1921
|
+
.update(metadata)
|
|
1922
|
+
.set({ propertyName: to })
|
|
1923
|
+
.where(and(eq(metadata.propertyId, propertyId), eq(metadata.propertyName, from)))
|
|
1924
|
+
.returning({ localId: metadata.localId });
|
|
1925
|
+
const legacy = await db
|
|
1926
|
+
.update(metadata)
|
|
1927
|
+
.set({ propertyName: to })
|
|
1928
|
+
.where(and(isNull(metadata.propertyId), eq(metadata.propertyName, from), eq(metadata.modelType, modelType)))
|
|
1929
|
+
.returning({ localId: metadata.localId });
|
|
1930
|
+
moved += byId.length + legacy.length;
|
|
1931
|
+
}
|
|
1932
|
+
if (moved > 0)
|
|
1933
|
+
logger$3(`[moveMetadataToRenamedProperty] moved ${moved} metadata rows ${oldName} -> ${newName}`);
|
|
1934
|
+
return moved;
|
|
1935
|
+
}
|
|
1604
1936
|
const getObjectForRow = (row) => {
|
|
1605
1937
|
const obj = {};
|
|
1606
1938
|
row.columnNames.forEach((colName, index) => {
|
|
@@ -1882,6 +2214,8 @@ const addSchemaToDb = async (schema, schemaFileId, schemaData, isDraft, isEdited
|
|
|
1882
2214
|
if (!db) {
|
|
1883
2215
|
throw new Error('Database not found');
|
|
1884
2216
|
}
|
|
2217
|
+
// The stored schema file may change its nameMatch levels (ADR 0009).
|
|
2218
|
+
clearNameMatchLevels();
|
|
1885
2219
|
// First, try to find existing schema by schemaFileId (preferred for change tracking)
|
|
1886
2220
|
if (schemaFileId) {
|
|
1887
2221
|
const existingByFileId = await db
|
|
@@ -2350,6 +2684,8 @@ const addModelsToDb = async (models$1, schema, modelRenames, schemaFileData) =>
|
|
|
2350
2684
|
if (!db) {
|
|
2351
2685
|
throw new Error('Database not found');
|
|
2352
2686
|
}
|
|
2687
|
+
// Model rows and their schema links decide which schema file's nameMatch applies (ADR 0009).
|
|
2688
|
+
clearNameMatchLevels();
|
|
2353
2689
|
// If schema is provided, add it to the database
|
|
2354
2690
|
// Note: schema might already be a database record (with id) if passed from importJsonSchema
|
|
2355
2691
|
let schemaRecord;
|
|
@@ -2504,27 +2840,8 @@ const addModelsToDb = async (models$1, schema, modelRenames, schemaFileData) =>
|
|
|
2504
2840
|
// If refValueType is not set, ensure it's null
|
|
2505
2841
|
propertyData.refValueType = null;
|
|
2506
2842
|
}
|
|
2507
|
-
//
|
|
2508
|
-
if
|
|
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
|
-
}
|
|
2843
|
+
// ADR 0008: a rename needs the property's id. A name that matches no stored property by id
|
|
2844
|
+
// or name is a new property, even if one of the same type was removed in the same edit.
|
|
2528
2845
|
if (existingProperty) {
|
|
2529
2846
|
// Mark this DB property as matched
|
|
2530
2847
|
matchedDbPropertyIds.add(existingProperty.id);
|
|
@@ -2582,6 +2899,16 @@ const addModelsToDb = async (models$1, schema, modelRenames, schemaFileData) =>
|
|
|
2582
2899
|
if (updatedFileId)
|
|
2583
2900
|
updatedPropertyFileIds.push(updatedFileId);
|
|
2584
2901
|
}
|
|
2902
|
+
if (existingProperty.name !== propertyName) {
|
|
2903
|
+
// Renamed (matched by id): its values move to the new name.
|
|
2904
|
+
await moveMetadataToRenamedProperty(db, {
|
|
2905
|
+
propertyId: existingProperty.id,
|
|
2906
|
+
modelType: easName(modelName),
|
|
2907
|
+
oldName: existingProperty.name,
|
|
2908
|
+
newName: propertyName,
|
|
2909
|
+
propertyDef: propertyValues,
|
|
2910
|
+
});
|
|
2911
|
+
}
|
|
2585
2912
|
}
|
|
2586
2913
|
else {
|
|
2587
2914
|
// Property doesn't exist, create it with schemaFileId
|
|
@@ -3524,6 +3851,7 @@ var db = /*#__PURE__*/Object.freeze({
|
|
|
3524
3851
|
getWatchedAddressesFromDb: getWatchedAddressesFromDb,
|
|
3525
3852
|
loadModelsFromDbForSchema: loadModelsFromDbForSchema,
|
|
3526
3853
|
migrateMetadataForPropertyRename: migrateMetadataForPropertyRename,
|
|
3854
|
+
moveMetadataToRenamedProperty: moveMetadataToRenamedProperty,
|
|
3527
3855
|
propertyStorageColumns: propertyStorageColumns,
|
|
3528
3856
|
renameModelInDb: renameModelInDb,
|
|
3529
3857
|
savePropertyToDb: savePropertyToDb,
|
|
@@ -3743,7 +4071,7 @@ const syncDbFiles = async (endpoints) => {
|
|
|
3743
4071
|
const getAppDbReady = async () => {
|
|
3744
4072
|
if (!BaseDb.isAppDbReady()) {
|
|
3745
4073
|
// Wait for ClientManager to be ready (DB_INIT state or later)
|
|
3746
|
-
const _mod_0 = await import('./ClientManager-
|
|
4074
|
+
const _mod_0 = await import('./ClientManager-DETTj0_z.js');
|
|
3747
4075
|
const _ns_0 = _mod_0.M;
|
|
3748
4076
|
const clientManagerMod = _ns_0;
|
|
3749
4077
|
const { getClient } = clientManagerMod;
|
|
@@ -4139,8 +4467,9 @@ const INTERNAL_DATA_TYPES = {
|
|
|
4139
4467
|
Text: {
|
|
4140
4468
|
eas: 'string',
|
|
4141
4469
|
},
|
|
4470
|
+
// ADR 0010: decimal strings, so negatives, fractions and values above 255 publish.
|
|
4142
4471
|
Number: {
|
|
4143
|
-
eas: '
|
|
4472
|
+
eas: 'string',
|
|
4144
4473
|
},
|
|
4145
4474
|
Image: {
|
|
4146
4475
|
eas: 'bytes32',
|
|
@@ -4487,9 +4816,6 @@ var generateId$1 = /*#__PURE__*/Object.freeze({
|
|
|
4487
4816
|
});
|
|
4488
4817
|
|
|
4489
4818
|
const logger = debug('seedSdk:shared:helpers');
|
|
4490
|
-
const toSnakeCase = (str) => {
|
|
4491
|
-
return str.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
|
|
4492
|
-
};
|
|
4493
4819
|
const getMimeType = (base64) => {
|
|
4494
4820
|
if (!base64) {
|
|
4495
4821
|
return null;
|
|
@@ -4639,5 +4965,5 @@ class BasePathResolver {
|
|
|
4639
4965
|
}
|
|
4640
4966
|
BasePathResolver._impl = null;
|
|
4641
4967
|
|
|
4642
|
-
export {
|
|
4643
|
-
//# sourceMappingURL=BasePathResolver-
|
|
4968
|
+
export { getCorrectId 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, nameMatchLevels as I, BasePathResolver as J, BaseFileManager as K, getPropertyIdForModelAndName as L, ModelPropertyDataTypes as M, resolveItemModelFileId as N, resolveSeedIdsFromRefString as O, Property as P, normalizeRelationPropertyValue as Q, isPublishedSeedRef as R, getStorageDirForDataType as S, THtmlEmbeddedDataUriPolicy as T, getContentSha256 as U, buildArweaveContentTags as V, getItemStorageSubdir as W, getItemStorageLocalFileName as X, addModelsToDb as Y, INIT_SCRIPT_SUCCESS_MESSAGE as Z, SCHEMA_TS as _, TProperty as a, getStorageTransactionIdForSeedUid as a$, SEED_CONFIG_FILE as a0, SEED_CONFIG_FALLBACKS as a1, isNode as a2, ZERO_BYTES32 as a3, resolveModelRecord as a4, getItemModelScope as a5, VERSION_SCHEMA_UID as a6, INTERNAL_PROPERTY_NAMES as a7, isStorageSeedRef as a8, defaultAttestationData as a9, closestImageSize as aA, contentSha256TagMatches as aB, ensureImageLocal as aC, getAddressesForItemsFilter as aD, getFeedItemStringField as aE, normalizeAddressConfig as aF, normalizeAddressList as aG, normalizeArweaveTxIdForEnsure as aH, normalizeFeedItemFields as aI, resolveMediaRef as aJ, isInternalSchema as aK, writeModelToDb as aL, writePropertyToDb as aM, addSchemaToDb as aN, renameModelInDb as aO, currentNameMatchLevels as aP, loadModelsFromDbForSchema as aQ, clearNameMatchLevels as aR, downloadAllFilesRequestHandler as aS, downloadAllFilesBinaryRequestHandler as aT, warnOnInvalidNameMatch as aU, INTERNAL_SCHEMA_IDS as aV, linkModelToSchema as aW, getWatchedAddressesFromDb as aX, getOwnedAddressesFromDb as aY, CLIENT_NOT_INITIALIZED as aZ, toSchemaPropertyName as a_, INTERNAL_DATA_TYPES as aa, listRelationEasPropertyName as ab, easPropertyNameForPublish as ac, isBrowser as ad, EAS_SEED_DATA_SYNCED_TO_DB_EVENT as ae, normalizePublisher as af, getAllAddressesFromDb as ag, loadNameMatchLevels as ah, scheduleBulkFilesDownloadFromEasSync as ai, generateId as aj, normalizeHexAddress as ak, toMetadataPropertyName as al, getItemStoragePropertiesForModel as am, getModelIdByFileId as an, getModelId as ao, setCachedPropertyRefresher as ap, getArweaveUrlForTransaction as aq, INTERNAL_STORAGE_MODEL_FILE_IDS as ar, CONTENT_SHA256_TAG as as, CONTENT_TYPE_TAG as at, ImageSize as au, SEED_PROTOCOL_SCHEMA_NAME as av, SeedModels as aw, VERSION_SCHEMA_DEF as ax, VERSION_SCHEMA_UID_OPTIMISM_SEPOLIA as ay, classifyMediaRef as az, TPropertyConstructor as b, convertTxIdToImage as b0, getMetadataPropertyNamesForQuery as b1, downloadTransactionIdWithDedupe as b2, resolveMetadataRecord as b3, getPropertyIdForSchemaFileId as b4, getDataTypeFromString as b5, getMimeType as b6, listRelationStoragePropertyName as b7, PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP as b8, getAlternatePropertyNameForInstanceLookup as b9, BaseDb$1 as ba, ModelSchema as bb, BaseFileManager$1 as bc, SchemaSchema as bd, ModelSchemaSchema as be, resolveModelRecord$1 as bf, db as bg, download as bh, generateId$1 as bi, 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 };
|
|
4969
|
+
//# sourceMappingURL=BasePathResolver-CsZHPrk9.js.map
|