@seedprotocol/sdk 0.3.0 → 0.3.1
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/{ArweaveClient-CmJYeuq1.js → ArweaveClient-C0g0es2v.js} +2 -2
- package/dist/{ArweaveClient-EXXrXUzz.js.map → ArweaveClient-C0g0es2v.js.map} +1 -1
- package/dist/{ArweaveClient-EXXrXUzz.js → ArweaveClient-CzkBgiZY.js} +2 -2
- package/dist/{ArweaveClient-CmJYeuq1.js.map → ArweaveClient-CzkBgiZY.js.map} +1 -1
- package/dist/{Db-CESKJH-G.js → Db-C4oog-0n.js} +3 -3
- package/dist/{Db-CESKJH-G.js.map → Db-C4oog-0n.js.map} +1 -1
- package/dist/{Db-DiTPSbQ8.js → Db-VPouegkr.js} +3 -3
- package/dist/{Db-DiTPSbQ8.js.map → Db-VPouegkr.js.map} +1 -1
- package/dist/{EasClient-BesHK2bO.js → EasClient-B9a3NsTi.js} +2 -2
- package/dist/{EasClient-BesHK2bO.js.map → EasClient-B9a3NsTi.js.map} +1 -1
- package/dist/{EasClient-Cop6WtWl.js → EasClient-DQ93i2ci.js} +2 -2
- package/dist/{EasClient-Cop6WtWl.js.map → EasClient-DQ93i2ci.js.map} +1 -1
- package/dist/{FileManager-DTzkncLh.js → FileManager-_ErxVuwb.js} +8 -5
- package/dist/FileManager-_ErxVuwb.js.map +1 -0
- package/dist/{Item-B5Tz-Y7t.js → Item-D9HFPxsK.js} +3 -3
- package/dist/{Item-B5Tz-Y7t.js.map → Item-D9HFPxsK.js.map} +1 -1
- package/dist/{ItemProperty-DBV0Iib_.js → ItemProperty-BdtvKrEy.js} +3 -3
- package/dist/{ItemProperty-DBV0Iib_.js.map → ItemProperty-BdtvKrEy.js.map} +1 -1
- package/dist/{QueryClient-C7a0NHCt.js → QueryClient-Bmnv_moN.js} +2 -2
- package/dist/{QueryClient-C7a0NHCt.js.map → QueryClient-Bmnv_moN.js.map} +1 -1
- package/dist/{QueryClient-BnwbHtqe.js → QueryClient-hzOtFe99.js} +2 -2
- package/dist/{QueryClient-BnwbHtqe.js.map → QueryClient-hzOtFe99.js.map} +1 -1
- package/dist/bin.js +5 -5
- package/dist/bin.js.map +1 -1
- package/dist/{constants-CWg2B3Au.js → constants-Bhl5dZpN.js} +4 -1
- package/dist/constants-Bhl5dZpN.js.map +1 -0
- package/dist/{index-CQ9FS10O.js → index-BAtjd9W-.js} +3 -3
- package/dist/index-BAtjd9W-.js.map +1 -0
- package/dist/{index-BHGJ-Es9.js → index-BSR5hv7Q.js} +59 -27
- package/dist/index-BSR5hv7Q.js.map +1 -0
- package/dist/main.js +2 -2
- package/dist/{seed.schema.config-DDzfQguf.js → seed.schema.config-BxJYabim.js} +3 -3
- package/dist/{seed.schema.config-DDzfQguf.js.map → seed.schema.config-BxJYabim.js.map} +1 -1
- package/dist/src/AppStateSchema.ts +10 -0
- package/dist/src/ArweaveClient.ts +13 -0
- package/dist/src/Attestation.ts +21 -0
- package/dist/src/BaseArweaveClient.ts +13 -0
- package/dist/src/BaseClientManager.ts +35 -0
- package/dist/src/BaseDb.ts +35 -0
- package/dist/src/BaseEasClient.ts +14 -0
- package/dist/src/BaseFileManager.ts +60 -0
- package/dist/src/BaseItem.ts +413 -0
- package/dist/src/BaseItemProperty.ts +416 -0
- package/dist/src/BaseQueryClient.ts +13 -0
- package/dist/src/ClientManager.ts +63 -0
- package/dist/src/ConfigSchema.ts +15 -0
- package/dist/src/Db.ts +82 -0
- package/dist/src/EasClient.ts +13 -0
- package/dist/src/FileDownloader.ts +63 -0
- package/dist/src/FileManager.ts +59 -0
- package/dist/src/IDb.ts +7 -0
- package/dist/src/IEasClient.ts +2 -0
- package/dist/src/IItem.ts +26 -0
- package/dist/src/IItemProperty.ts +28 -0
- package/dist/src/IQueryClient.ts +11 -0
- package/dist/src/ImageResizer.ts +81 -0
- package/dist/src/Item.ts +12 -0
- package/dist/src/ItemProperty.ts +9 -0
- package/dist/src/MetadataSchema.ts +28 -0
- package/dist/src/ModelSchema.ts +46 -0
- package/dist/src/ModelUidSchema.ts +16 -0
- package/dist/src/PropertyUidSchema.ts +16 -0
- package/dist/src/QueryClient.ts +26 -0
- package/dist/src/Schema.ts +17 -0
- package/dist/src/SeedProtocolSdk.d.ts +19 -0
- package/dist/src/SeedSchema.ts +29 -0
- package/dist/src/VersionSchema.ts +16 -0
- package/dist/src/actors.ts +295 -0
- package/dist/src/addModelsToDb.ts +152 -0
- package/dist/src/allItems.ts +31 -0
- package/dist/src/analyzeInput.ts +144 -0
- package/dist/src/browser.app.db.config.ts +27 -0
- package/dist/src/browser.ts +30 -0
- package/dist/src/checkStatus.ts +57 -0
- package/dist/src/clientManagerMachine.ts +59 -0
- package/dist/src/configureFs.ts +98 -0
- package/dist/src/connectToDb.ts +41 -0
- package/dist/src/connectionManager.ts +67 -0
- package/dist/src/constants.ts +125 -0
- package/dist/src/content-hash.ts +30 -0
- package/dist/src/create.ts +39 -0
- package/dist/src/createMetadata.ts +77 -0
- package/dist/src/createNewItem.ts +61 -0
- package/dist/src/createPublishAttempt.ts +16 -0
- package/dist/src/createSeed.ts +31 -0
- package/dist/src/createSeeds.ts +24 -0
- package/dist/src/createVersion.ts +33 -0
- package/dist/src/dbMachine.ts +182 -0
- package/dist/src/deleteItem.ts +19 -0
- package/dist/src/download.ts +208 -0
- package/dist/src/drizzle.ts +78 -0
- package/dist/src/eas.ts +40 -0
- package/dist/src/environment.ts +35 -0
- package/dist/src/eventBus.ts +5 -0
- package/dist/src/events.ts +14 -0
- package/dist/src/fetchDataFromEas.ts +94 -0
- package/dist/src/fetchDbData.ts +19 -0
- package/dist/src/fetchRelatedItems.ts +184 -0
- package/dist/src/fetchSeeds.ts +45 -0
- package/dist/src/fetchVersions.ts +49 -0
- package/dist/src/files.ts +81 -0
- package/dist/src/filesDownload.ts +326 -0
- package/dist/src/fragment-masking.ts +87 -0
- package/dist/src/getExistingItem.ts +60 -0
- package/dist/src/getItem.ts +32 -0
- package/dist/src/getItemData.ts +99 -0
- package/dist/src/getItemProperties.ts +56 -0
- package/dist/src/getItemProperty.ts +34 -0
- package/dist/src/getItems.ts +70 -0
- package/dist/src/getMetadata.ts +40 -0
- package/dist/src/getModelSchemas.ts +89 -0
- package/dist/src/getPropertyData.ts +50 -0
- package/dist/src/getPublishPayload.ts +355 -0
- package/dist/src/getPublishUploads.ts +207 -0
- package/dist/src/getRelationValueData.ts +27 -0
- package/dist/src/getSchemaForItemProperty.ts +68 -0
- package/dist/src/getSchemaForModel.ts +42 -0
- package/dist/src/getSchemaUidForModel.ts +32 -0
- package/dist/src/getSeedData.ts +34 -0
- package/dist/src/getSegmentedItemProperties.ts +65 -0
- package/dist/src/getStorageTransactionIdForSeedUid.ts +38 -0
- package/dist/src/getVersionData.ts +46 -0
- package/dist/src/getVersionsForVersionUids.ts +39 -0
- package/dist/src/globalMachine.ts +280 -0
- package/dist/src/gql.ts +118 -0
- package/dist/src/graphql.ts +3209 -0
- package/dist/src/helpers.ts +273 -0
- package/dist/src/hydrateExistingItem.ts +137 -0
- package/dist/src/hydrateFromDb.ts +270 -0
- package/dist/src/hydrateNewItem.ts +34 -0
- package/dist/src/imageResize.ts +507 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.ts +4 -0
- package/dist/src/initialize.ts +124 -0
- package/dist/src/internalMachine.ts +241 -0
- package/dist/src/itemMachineAll.ts +157 -0
- package/dist/src/itemMachineSingle.ts +158 -0
- package/dist/src/loadAppDb.ts +44 -0
- package/dist/src/machines.ts +66 -0
- package/dist/src/metadataLatest.ts +34 -0
- package/dist/src/migrate.ts +57 -0
- package/dist/src/model.ts +72 -0
- package/dist/src/modelClass.ts +19 -0
- package/dist/src/node.app.db.config.ts +41 -0
- package/dist/src/prepareDb.ts +29 -0
- package/dist/src/preparePublishRequestData.ts +81 -0
- package/dist/src/processItems.ts +74 -0
- package/dist/src/property.ts +156 -0
- package/dist/src/propertyMachine.ts +202 -0
- package/dist/src/publish.ts +28 -0
- package/dist/src/publishMachine.ts +77 -0
- package/dist/src/queries.ts +13 -0
- package/dist/src/recoverDeletedItem.ts +14 -0
- package/dist/src/reload.ts +33 -0
- package/dist/src/request.ts +45 -0
- package/dist/src/requestAll.ts +157 -0
- package/dist/src/resolveRelatedValue.ts +367 -0
- package/dist/src/resolveRemoteStorage.ts +88 -0
- package/dist/src/saveAppState.ts +50 -0
- package/dist/src/saveConfig.ts +106 -0
- package/dist/src/saveDataToDb.ts +145 -0
- package/dist/src/saveImageSrc.ts +242 -0
- package/dist/src/saveItemStorage.ts +156 -0
- package/dist/src/saveMetadata.ts +18 -0
- package/dist/src/savePublishService.ts +30 -0
- package/dist/src/saveRelation.ts +112 -0
- package/dist/src/seed.schema.config.ts +25 -0
- package/dist/src/seed.ts +10 -0
- package/dist/src/seedProtocol.ts +17 -0
- package/dist/src/services.ts +365 -0
- package/dist/src/setAddresses.ts +16 -0
- package/dist/src/sqlWasmClient.ts +88 -0
- package/dist/src/syncDbWithEas.ts +628 -0
- package/dist/src/trash.ts +29 -0
- package/dist/src/ts-to-proto.ts +101 -0
- package/dist/src/types.ts +12 -0
- package/dist/src/updateItemPropertyValue.ts +243 -0
- package/dist/src/updateMachineContext.ts +21 -0
- package/dist/src/updateMetadata.ts +59 -0
- package/dist/src/upload.ts +86 -0
- package/dist/src/validate.ts +45 -0
- package/dist/src/validateInput.ts +43 -0
- package/dist/src/validateItemData.ts +20 -0
- package/dist/src/versionData.ts +24 -0
- package/dist/src/waitForDb.ts +25 -0
- package/dist/src/waitForFiles.ts +41 -0
- package/dist/src/wasm.d.ts +8300 -0
- package/dist/types/scripts/bin.d.ts.map +1 -1
- package/dist/types/src/browser/helpers/FileManager.d.ts +2 -1
- package/dist/types/src/browser/helpers/FileManager.d.ts.map +1 -1
- package/dist/types/src/helpers/FileManager/BaseFileManager.d.ts +1 -0
- package/dist/types/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
- package/dist/types/src/node/helpers/FileManager.d.ts +2 -1
- package/dist/types/src/node/helpers/FileManager.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/FileManager-DTzkncLh.js.map +0 -1
- package/dist/constants-CWg2B3Au.js.map +0 -1
- package/dist/index-BHGJ-Es9.js.map +0 -1
- package/dist/index-CQ9FS10O.js.map +0 -1
- package/dist/package.json +0 -189
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Decorator, Project } from 'ts-morph'
|
|
2
|
+
import { Field, Type } from 'protobufjs'
|
|
3
|
+
import fs from 'fs'
|
|
4
|
+
|
|
5
|
+
type TsToProtoOptions = {
|
|
6
|
+
tsFilePath: string
|
|
7
|
+
tsConfigPath: string
|
|
8
|
+
outputFilePath: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type TsToProto = (options: TsToProtoOptions) => void
|
|
12
|
+
|
|
13
|
+
export const tsToProto: TsToProto = ({
|
|
14
|
+
tsFilePath,
|
|
15
|
+
tsConfigPath,
|
|
16
|
+
outputFilePath,
|
|
17
|
+
}) => {
|
|
18
|
+
// Initialize the TypeScript project
|
|
19
|
+
const project = new Project({
|
|
20
|
+
tsConfigFilePath: tsConfigPath,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
// Add the source file
|
|
24
|
+
const sourceFile = project.addSourceFileAtPath(tsFilePath)
|
|
25
|
+
|
|
26
|
+
// Helper function to extract decorator arguments
|
|
27
|
+
const getDecoratorArgument = (decorator: Decorator): string => {
|
|
28
|
+
const callExpression = decorator.getCallExpression()
|
|
29
|
+
if (callExpression) {
|
|
30
|
+
const args = callExpression.getArguments()
|
|
31
|
+
if (args.length > 0) {
|
|
32
|
+
return args[0].getText().replace(/['"]/g, '')
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return ''
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Process each class
|
|
39
|
+
const classes = sourceFile.getClasses()
|
|
40
|
+
const protoClasses: { [key: string]: Type } = {}
|
|
41
|
+
|
|
42
|
+
classes.forEach((cls) => {
|
|
43
|
+
const className = cls.getName()
|
|
44
|
+
if (!className) {
|
|
45
|
+
throw new Error('Class name not found')
|
|
46
|
+
}
|
|
47
|
+
const type = new Type(className)
|
|
48
|
+
|
|
49
|
+
// Process each property
|
|
50
|
+
cls.getProperties().forEach((prop, index) => {
|
|
51
|
+
const propName = prop.getName()
|
|
52
|
+
const decorators = prop.getDecorators()
|
|
53
|
+
|
|
54
|
+
decorators.forEach((decorator) => {
|
|
55
|
+
const decoratorName = decorator.getName()
|
|
56
|
+
switch (decoratorName) {
|
|
57
|
+
case 'Text':
|
|
58
|
+
type.add(new Field(propName, type.fieldsArray.length + 1, 'string'))
|
|
59
|
+
break
|
|
60
|
+
case 'ImageSrc':
|
|
61
|
+
type.add(new Field(propName, type.fieldsArray.length + 1, 'string'))
|
|
62
|
+
break
|
|
63
|
+
case 'Relation':
|
|
64
|
+
const relatedType = getDecoratorArgument(decorator)
|
|
65
|
+
type.add(
|
|
66
|
+
new Field(propName, type.fieldsArray.length + 1, relatedType),
|
|
67
|
+
)
|
|
68
|
+
break
|
|
69
|
+
case 'List':
|
|
70
|
+
const listType = getDecoratorArgument(decorator)
|
|
71
|
+
type.add(
|
|
72
|
+
new Field(
|
|
73
|
+
propName,
|
|
74
|
+
type.fieldsArray.length + 1,
|
|
75
|
+
listType,
|
|
76
|
+
'repeated',
|
|
77
|
+
),
|
|
78
|
+
)
|
|
79
|
+
break
|
|
80
|
+
default:
|
|
81
|
+
break
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
protoClasses[className] = type
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
// Generate .proto content
|
|
90
|
+
let protoContent = 'syntax = "proto3";\n\n'
|
|
91
|
+
Object.values(protoClasses).forEach((type) => {
|
|
92
|
+
protoContent += `message ${type.name} {\n`
|
|
93
|
+
for (const field of type.fieldsArray) {
|
|
94
|
+
protoContent += ` ${field.repeated ? 'repeated' : ''} ${field.type} ${field.name} = ${field.id};\n`
|
|
95
|
+
}
|
|
96
|
+
protoContent += '}\n'
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// Write to .proto file
|
|
100
|
+
fs.writeFileSync(outputFilePath, protoContent)
|
|
101
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type SqliteWasmResult = {
|
|
2
|
+
type: string | null
|
|
3
|
+
row: string[] | null
|
|
4
|
+
rowNumber: number | null
|
|
5
|
+
columnNames: string[]
|
|
6
|
+
}
|
|
7
|
+
type SqliteWasmCallback = (result: SqliteWasmResult) => void
|
|
8
|
+
|
|
9
|
+
type ReturnObj = {
|
|
10
|
+
database: string
|
|
11
|
+
[key: string]: string | number | null | undefined | string[]
|
|
12
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { escapeSqliteString } from '@/helpers/db'
|
|
2
|
+
import { metadata, MetadataType } from '@/seedSchema'
|
|
3
|
+
import { and, eq, sql } from 'drizzle-orm'
|
|
4
|
+
import { getSeedData } from '@/db/read/getSeedData'
|
|
5
|
+
import { getVersionData } from '@/db/read/getVersionData'
|
|
6
|
+
import { generateId } from '@/helpers'
|
|
7
|
+
import debug from 'debug'
|
|
8
|
+
import { eventEmitter } from '@/eventBus'
|
|
9
|
+
import { BaseDb } from '@/db/Db/BaseDb'
|
|
10
|
+
const logger = debug('app:write:updateItemPropertyValue')
|
|
11
|
+
|
|
12
|
+
const sendItemUpdateEvent = ({ modelName, seedLocalId, seedUid }: { modelName: string, seedLocalId: string, seedUid: string }) => {
|
|
13
|
+
if (!modelName || (!seedLocalId && !seedUid)) {
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
// eventEmitter.emit(`item.${modelName}.${seedUid || seedLocalId}.update`)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type UpdateItemPropertyValueResult = {
|
|
20
|
+
localId: string
|
|
21
|
+
schemaUid: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type UpdateItemPropertyValue = (props: Partial<MetadataType>) => Promise<UpdateItemPropertyValueResult | undefined>
|
|
25
|
+
|
|
26
|
+
export const updateItemPropertyValue: UpdateItemPropertyValue = async ({
|
|
27
|
+
localId,
|
|
28
|
+
propertyName,
|
|
29
|
+
newValue,
|
|
30
|
+
seedUid,
|
|
31
|
+
seedLocalId,
|
|
32
|
+
modelName,
|
|
33
|
+
refSeedType,
|
|
34
|
+
refResolvedValue,
|
|
35
|
+
refResolvedDisplayValue,
|
|
36
|
+
versionLocalId,
|
|
37
|
+
versionUid,
|
|
38
|
+
schemaUid,
|
|
39
|
+
localStorageDir,
|
|
40
|
+
}) => {
|
|
41
|
+
if (!localId && !seedLocalId) {
|
|
42
|
+
logger(
|
|
43
|
+
`[db/write] [updateItemPropertyValue] no propertyLocalId or seedLocalId for property: ${propertyName}`,
|
|
44
|
+
)
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let safeNewValue = newValue
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
typeof newValue === 'string' &&
|
|
52
|
+
!refResolvedDisplayValue &&
|
|
53
|
+
!refResolvedValue
|
|
54
|
+
) {
|
|
55
|
+
safeNewValue = escapeSqliteString(newValue)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const appDb = BaseDb.getAppDb()
|
|
59
|
+
|
|
60
|
+
const rows = await appDb
|
|
61
|
+
.select()
|
|
62
|
+
.from(metadata)
|
|
63
|
+
.where(
|
|
64
|
+
and(
|
|
65
|
+
eq(metadata.propertyName, propertyName!),
|
|
66
|
+
eq(metadata.seedLocalId, seedLocalId!),
|
|
67
|
+
),
|
|
68
|
+
)
|
|
69
|
+
.orderBy(sql.raw('COALESCE(attestation_created_at, created_at) DESC'))
|
|
70
|
+
|
|
71
|
+
// const mostRecentRecordStatement = `SELECT local_id,
|
|
72
|
+
// uid,
|
|
73
|
+
// property_name,
|
|
74
|
+
// property_value,
|
|
75
|
+
// model_type,
|
|
76
|
+
// seed_uid,
|
|
77
|
+
// seed_local_id,
|
|
78
|
+
// version_local_id,
|
|
79
|
+
// version_uid,
|
|
80
|
+
// schema_uid,
|
|
81
|
+
// eas_data_type
|
|
82
|
+
// FROM metadata
|
|
83
|
+
// WHERE property_name = '${propertyName}'
|
|
84
|
+
// AND seed_local_id = '${seedLocalId}'
|
|
85
|
+
// ORDER BY COALESCE(attestation_created_at, created_at) DESC;`
|
|
86
|
+
//
|
|
87
|
+
// const { rows } = await runQueryForStatement(mostRecentRecordStatement)
|
|
88
|
+
|
|
89
|
+
if (rows && rows.length > 0) {
|
|
90
|
+
const {
|
|
91
|
+
localId,
|
|
92
|
+
uid,
|
|
93
|
+
propertyName: propertyNameFromDb,
|
|
94
|
+
propertyValue: propertyValueFromDb,
|
|
95
|
+
modelType,
|
|
96
|
+
seedUid,
|
|
97
|
+
seedLocalId: seedLocalIdFromDb,
|
|
98
|
+
versionLocalId,
|
|
99
|
+
versionUid,
|
|
100
|
+
schemaUid,
|
|
101
|
+
easDataType,
|
|
102
|
+
localStorageDir: localStorageDirFromDb,
|
|
103
|
+
refSeedType: refSeedTypeFromDb,
|
|
104
|
+
refResolvedValue: refResolvedValueFromDb,
|
|
105
|
+
refResolvedDisplayValue: refResolvedDisplayValueFromDb,
|
|
106
|
+
} = rows[0]
|
|
107
|
+
|
|
108
|
+
if (
|
|
109
|
+
propertyValueFromDb === newValue &&
|
|
110
|
+
modelType === modelName?.toLowerCase() &&
|
|
111
|
+
refSeedTypeFromDb === refSeedType &&
|
|
112
|
+
refResolvedValueFromDb === refResolvedValue
|
|
113
|
+
) {
|
|
114
|
+
logger(
|
|
115
|
+
`[db/write] [updateItemPropertyValue] value is the same as most recent record for property: ${propertyNameFromDb}`,
|
|
116
|
+
)
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// This means we already have a local-only record so we should just update that one
|
|
121
|
+
if (!uid) {
|
|
122
|
+
const updatePropertyStatement = `UPDATE metadata
|
|
123
|
+
SET property_value = '${safeNewValue}',
|
|
124
|
+
ref_seed_type = ${refSeedType ? `'${refSeedType}'` : 'NULL'},
|
|
125
|
+
ref_resolved_value = ${refResolvedValue ? `'${refResolvedValue}'` : 'NULL'},
|
|
126
|
+
ref_resolved_display_value = ${refResolvedDisplayValue ? `'${refResolvedDisplayValue}'` : 'NULL'},
|
|
127
|
+
updated_at = ${Date.now()}
|
|
128
|
+
WHERE local_id = '${localId}';`
|
|
129
|
+
|
|
130
|
+
await appDb.run(sql.raw(updatePropertyStatement))
|
|
131
|
+
|
|
132
|
+
sendItemUpdateEvent({ modelName, seedLocalId, seedUid })
|
|
133
|
+
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const seedDataFromDb = await getSeedData({ seedLocalId })
|
|
138
|
+
const versionDataFromDb = await getVersionData({ localId: versionLocalId })
|
|
139
|
+
|
|
140
|
+
// Here we don't have a local-only record so we need to create a new one
|
|
141
|
+
const newLocalId = generateId()
|
|
142
|
+
|
|
143
|
+
const newPropertyStatement = `INSERT INTO metadata (local_id,
|
|
144
|
+
property_name,
|
|
145
|
+
property_value,
|
|
146
|
+
model_type,
|
|
147
|
+
seed_uid,
|
|
148
|
+
seed_local_id,
|
|
149
|
+
version_local_id,
|
|
150
|
+
version_uid,
|
|
151
|
+
schema_uid,
|
|
152
|
+
eas_data_type,
|
|
153
|
+
ref_seed_type,
|
|
154
|
+
ref_resolved_value,
|
|
155
|
+
ref_resolved_display_value,
|
|
156
|
+
local_storage_dir,
|
|
157
|
+
created_at)
|
|
158
|
+
VALUES ('${newLocalId}',
|
|
159
|
+
'${propertyNameFromDb}',
|
|
160
|
+
'${safeNewValue}',
|
|
161
|
+
'${modelType || modelName?.toLowerCase()}',
|
|
162
|
+
${seedDataFromDb?.uid ? `'${seedDataFromDb.uid}'` : 'NULL'},
|
|
163
|
+
'${seedLocalIdFromDb}',
|
|
164
|
+
'${versionLocalId}',
|
|
165
|
+
${versionDataFromDb?.uid ? `'${versionDataFromDb.uid}'` : 'NULL'},
|
|
166
|
+
'${schemaUid}',
|
|
167
|
+
${easDataType ? `'${easDataType}'` : 'NULL'},
|
|
168
|
+
${refSeedType ? `'${refSeedType}'` : 'NULL'},
|
|
169
|
+
${refResolvedValue ? `'${refResolvedValue}'` : 'NULL'},
|
|
170
|
+
${refResolvedDisplayValue ? `'${refResolvedDisplayValue}'` : 'NULL'},
|
|
171
|
+
${localStorageDir ? `'${localStorageDir}'` : 'NULL'},
|
|
172
|
+
${Date.now()});`
|
|
173
|
+
|
|
174
|
+
await appDb.run(sql.raw(newPropertyStatement))
|
|
175
|
+
|
|
176
|
+
sendItemUpdateEvent({ modelName, seedLocalId, seedUid })
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
localId: newLocalId,
|
|
180
|
+
schemaUid,
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Here there are no records for this property on this seed so we should create one
|
|
185
|
+
|
|
186
|
+
const newLocalId = generateId()
|
|
187
|
+
|
|
188
|
+
if (!seedUid) {
|
|
189
|
+
const seedData = await getSeedData({ seedLocalId })
|
|
190
|
+
if (seedData) {
|
|
191
|
+
seedUid = seedData.uid
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (!versionUid) {
|
|
196
|
+
const versionData = await getVersionData({ localId: versionLocalId })
|
|
197
|
+
if (versionData) {
|
|
198
|
+
versionUid = versionData.uid
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const newPropertyStatement = `INSERT INTO metadata (local_id,
|
|
203
|
+
property_name,
|
|
204
|
+
property_value,
|
|
205
|
+
model_type,
|
|
206
|
+
seed_uid,
|
|
207
|
+
seed_local_id,
|
|
208
|
+
version_local_id,
|
|
209
|
+
version_uid,
|
|
210
|
+
schema_uid,
|
|
211
|
+
ref_seed_type,
|
|
212
|
+
ref_resolved_value,
|
|
213
|
+
ref_resolved_display_value,
|
|
214
|
+
local_storage_dir,
|
|
215
|
+
created_at)
|
|
216
|
+
VALUES ('${newLocalId}',
|
|
217
|
+
'${propertyName}',
|
|
218
|
+
'${safeNewValue}',
|
|
219
|
+
'${modelName?.toLowerCase()}',
|
|
220
|
+
${seedUid ? `'${seedUid}'` : 'NULL'},
|
|
221
|
+
'${seedLocalId}',
|
|
222
|
+
'${versionLocalId}',
|
|
223
|
+
${versionUid ? `'${versionUid}'` : 'NULL'},
|
|
224
|
+
'${schemaUid}',
|
|
225
|
+
${refSeedType ? `'${refSeedType}'` : 'NULL'},
|
|
226
|
+
${refResolvedValue ? `'${refResolvedValue}'` : 'NULL'},
|
|
227
|
+
${refResolvedDisplayValue ? `'${refResolvedDisplayValue}'` : 'NULL'},
|
|
228
|
+
${localStorageDir ? `'${localStorageDir}'` : 'NULL'},
|
|
229
|
+
${Date.now()});`
|
|
230
|
+
|
|
231
|
+
await appDb.run(sql.raw(newPropertyStatement))
|
|
232
|
+
|
|
233
|
+
sendItemUpdateEvent({ modelName, seedLocalId, seedUid })
|
|
234
|
+
|
|
235
|
+
return {
|
|
236
|
+
localId: newLocalId,
|
|
237
|
+
schemaUid,
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (!seedLocalId && propertyName && modelName && newValue) {
|
|
241
|
+
// TODO: Does this ever happen? If so, what should we do?
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ActionFunction, assign } from 'xstate'
|
|
2
|
+
|
|
3
|
+
type UpdateMachineContext = {
|
|
4
|
+
actions: ActionFunction<any, any, any, any, any, any, any, any, any>[] | any
|
|
5
|
+
}
|
|
6
|
+
export const updateMachineContext: UpdateMachineContext = {
|
|
7
|
+
actions: assign(({ context, event }) => {
|
|
8
|
+
const newContext = Object.assign({}, context)
|
|
9
|
+
|
|
10
|
+
for (let i = 0; i < Object.keys(event).length; i++) {
|
|
11
|
+
const key = Object.keys(event)[i]
|
|
12
|
+
if (key === 'type') {
|
|
13
|
+
continue
|
|
14
|
+
}
|
|
15
|
+
newContext[key] = event[key]
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
...newContext,
|
|
19
|
+
}
|
|
20
|
+
}),
|
|
21
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { metadata, MetadataType } from '@/seedSchema'
|
|
2
|
+
import { BaseDb } from '@/db/Db/BaseDb'
|
|
3
|
+
import { eq } from 'drizzle-orm'
|
|
4
|
+
import { PropertyType } from '@/types'
|
|
5
|
+
import { BaseQueryClient } from '@/helpers/QueryClient/BaseQueryClient'
|
|
6
|
+
import { BaseEasClient } from '@/helpers/EasClient/BaseEasClient'
|
|
7
|
+
import { INTERNAL_DATA_TYPES } from '@/helpers/constants'
|
|
8
|
+
import { toSnakeCase } from 'drizzle-orm/casing'
|
|
9
|
+
import { Schema } from '@/graphql/gql/graphql'
|
|
10
|
+
import { GET_SCHEMA_BY_NAME } from '@/Item/queries'
|
|
11
|
+
|
|
12
|
+
type UpdateMetadata = (
|
|
13
|
+
metadataValues: Partial<MetadataType>,
|
|
14
|
+
propertyRecordSchema?: PropertyType | undefined,
|
|
15
|
+
) => Promise<MetadataType>
|
|
16
|
+
|
|
17
|
+
export const updateMetadata: UpdateMetadata = async (metadataValues, propertyRecordSchema) => {
|
|
18
|
+
const appDb = BaseDb.getAppDb()
|
|
19
|
+
|
|
20
|
+
const { localId, ...rest } = metadataValues
|
|
21
|
+
|
|
22
|
+
if (!localId) {
|
|
23
|
+
throw new Error('No localId provided to updateMetadata')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const isItemStorage = propertyRecordSchema && propertyRecordSchema.storageType === 'ItemStorage'
|
|
27
|
+
|
|
28
|
+
if (
|
|
29
|
+
!isItemStorage &&
|
|
30
|
+
propertyRecordSchema &&
|
|
31
|
+
(!metadataValues.schemaUid || metadataValues.schemaUid === 'undefined' )
|
|
32
|
+
) {
|
|
33
|
+
const queryClient = BaseQueryClient.getQueryClient()
|
|
34
|
+
const easClient = BaseEasClient.getEasClient()
|
|
35
|
+
|
|
36
|
+
const easDataType = INTERNAL_DATA_TYPES[propertyRecordSchema.dataType].eas
|
|
37
|
+
|
|
38
|
+
const propertyNameSnakeCase = toSnakeCase(metadataValues.propertyName)
|
|
39
|
+
|
|
40
|
+
const queryResult = await queryClient.fetchQuery({
|
|
41
|
+
queryKey: [`getSchemaByName${metadataValues.propertyName}`],
|
|
42
|
+
queryFn: async (): Promise<{schemas: Schema[]}> =>
|
|
43
|
+
easClient.request(GET_SCHEMA_BY_NAME, {
|
|
44
|
+
where: {
|
|
45
|
+
schema: {
|
|
46
|
+
equals: `${easDataType} ${propertyNameSnakeCase}`,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
if (queryResult && queryResult.schemas.length > 0) {
|
|
53
|
+
metadataValues.schemaUid = queryResult.schemas[0].id
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
await appDb.update(metadata).set(rest).where(eq(metadata.localId, localId))
|
|
59
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { EventObject, fromCallback } from 'xstate'
|
|
2
|
+
import { FromCallbackInput, PublishMachineContext } from '@/types'
|
|
3
|
+
import { BaseItem } from '@/Item/BaseItem'
|
|
4
|
+
import debug from 'debug'
|
|
5
|
+
import { getCorrectId } from '@/helpers'
|
|
6
|
+
|
|
7
|
+
const logger = debug('app:services:publish:actors:upload')
|
|
8
|
+
|
|
9
|
+
type UploadItem = {
|
|
10
|
+
sourceFilePath: string
|
|
11
|
+
fileSize: number
|
|
12
|
+
filename: string
|
|
13
|
+
seedLocalId?: string
|
|
14
|
+
metadataLocalId?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const upload = fromCallback<
|
|
18
|
+
EventObject,
|
|
19
|
+
FromCallbackInput<PublishMachineContext>
|
|
20
|
+
>(({ sendBack, input: { context } }) => {
|
|
21
|
+
const { localId } = context
|
|
22
|
+
|
|
23
|
+
const _upload = async () => {
|
|
24
|
+
const item = await BaseItem.find({ seedLocalId: localId })
|
|
25
|
+
|
|
26
|
+
if (!item) {
|
|
27
|
+
logger('no item with localId', localId)
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const editedProperties = await item.getEditedProperties()
|
|
32
|
+
|
|
33
|
+
for (const propertyData of editedProperties) {
|
|
34
|
+
if (propertyData.refSeedType === 'image') {
|
|
35
|
+
// Check sha256 of local file against sha256 of remote files
|
|
36
|
+
// If different, add this file to uploadItems
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const uploadItems = []
|
|
41
|
+
|
|
42
|
+
for (const editedPropertyData of editedProperties) {
|
|
43
|
+
const propertyName = editedPropertyData.propertyName
|
|
44
|
+
const editedProperty = item.properties[propertyName]
|
|
45
|
+
|
|
46
|
+
if (!editedProperty || !editedProperty.propertyDef) {
|
|
47
|
+
continue
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (
|
|
51
|
+
editedProperty.propertyDef.refValueType &&
|
|
52
|
+
editedProperty.propertyDef.refValueType === 'ImageSrc'
|
|
53
|
+
) {
|
|
54
|
+
const context = editedProperty.getService().getSnapshot().context
|
|
55
|
+
const imageSeedId = context.propertyValue
|
|
56
|
+
const { localId, uid } = getCorrectId(imageSeedId)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (
|
|
60
|
+
editedProperty.propertyDef.storageType === 'ItemStorage' &&
|
|
61
|
+
editedProperty.propertyDef.localStorageDir
|
|
62
|
+
) {
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (uploadItems.length === 0) {
|
|
67
|
+
return true
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// const turbo = TurboFactory.unauthenticated()
|
|
71
|
+
|
|
72
|
+
// turbo.uploadSignedDataItem()
|
|
73
|
+
//
|
|
74
|
+
// const { id, owner, dataCaches, fastFinalityIndexes } = await turbo.uploadFile(() => {
|
|
75
|
+
// fileStreamFactory => () => fs.createReadStream(filePath),
|
|
76
|
+
// fileSizeFactory => () => fileSize,
|
|
77
|
+
// });
|
|
78
|
+
return false
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
_upload().then((isValid) => {
|
|
82
|
+
if (isValid) {
|
|
83
|
+
sendBack({ type: 'uploadSuccess' })
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { EventObject, fromCallback } from 'xstate'
|
|
2
|
+
import { DbServiceContext, FromCallbackInput } from '@/types/machines'
|
|
3
|
+
import fs from '@zenfs/core'
|
|
4
|
+
import {
|
|
5
|
+
DB_VALIDATING_SUCCESS,
|
|
6
|
+
DB_VALIDATING_WAIT,
|
|
7
|
+
} from '@/services/internal/constants'
|
|
8
|
+
|
|
9
|
+
export const validate = fromCallback<
|
|
10
|
+
EventObject,
|
|
11
|
+
FromCallbackInput<DbServiceContext>
|
|
12
|
+
>(({ sendBack, input: { context } }) => {
|
|
13
|
+
const { pathToDir, pathToDb } = context
|
|
14
|
+
|
|
15
|
+
const pathsToCheck = [
|
|
16
|
+
pathToDir,
|
|
17
|
+
`${pathToDir}/db`,
|
|
18
|
+
`${pathToDir}/db/meta`,
|
|
19
|
+
`${pathToDir}/db/meta/_journal.json`,
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
const _validate = async (): Promise<boolean> => {
|
|
23
|
+
// If any of the necessary files don't exist, we wipe them all and recreate
|
|
24
|
+
let exists = false
|
|
25
|
+
|
|
26
|
+
for (const path of pathsToCheck) {
|
|
27
|
+
exists = await fs.promises.exists(path)
|
|
28
|
+
if (!exists) {
|
|
29
|
+
sendBack({
|
|
30
|
+
type: DB_VALIDATING_WAIT,
|
|
31
|
+
})
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return exists
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
_validate().then((allFilesExist) => {
|
|
39
|
+
if (allFilesExist) {
|
|
40
|
+
sendBack({ type: DB_VALIDATING_SUCCESS, pathToDb, pathToDir })
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
sendBack({ type: DB_VALIDATING_WAIT })
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { EventObject, fromCallback } from 'xstate'
|
|
2
|
+
import { INTERNAL_VALIDATING_INPUT_SUCCESS, ARWEAVE_HOST } from '@/services/internal/constants'
|
|
3
|
+
import { FromCallbackInput, InternalMachineContext } from '@/types'
|
|
4
|
+
import { isBrowser, isNode } from '@/helpers/environment'
|
|
5
|
+
|
|
6
|
+
export const validateInput = fromCallback<
|
|
7
|
+
EventObject,
|
|
8
|
+
FromCallbackInput<InternalMachineContext>
|
|
9
|
+
>(
|
|
10
|
+
({ sendBack, input: { context } }) => {
|
|
11
|
+
|
|
12
|
+
const { endpoints, addresses, arweaveDomain } = context
|
|
13
|
+
let { filesDir } = context
|
|
14
|
+
|
|
15
|
+
if (!endpoints || !endpoints.filePaths || !endpoints.files) {
|
|
16
|
+
throw new Error('validateInput called with invalid endpoints')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!filesDir) {
|
|
20
|
+
if (isBrowser()) {
|
|
21
|
+
filesDir = '/'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!isBrowser()) {
|
|
25
|
+
throw new Error('validateInput called with invalid filesDir')
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const _validateInput = async (): Promise<void> => {
|
|
30
|
+
sendBack({
|
|
31
|
+
type: INTERNAL_VALIDATING_INPUT_SUCCESS,
|
|
32
|
+
endpoints,
|
|
33
|
+
addresses,
|
|
34
|
+
filesDir,
|
|
35
|
+
arweaveDomain: arweaveDomain || ARWEAVE_HOST,
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
_validateInput().then(() => {
|
|
40
|
+
return
|
|
41
|
+
})
|
|
42
|
+
},
|
|
43
|
+
)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EventObject, fromCallback } from 'xstate'
|
|
2
|
+
import { FromCallbackInput, PublishMachineContext } from '@/types'
|
|
3
|
+
|
|
4
|
+
export const validateItemData = fromCallback<
|
|
5
|
+
EventObject,
|
|
6
|
+
FromCallbackInput<PublishMachineContext>
|
|
7
|
+
>(({ sendBack, input: { context } }) => {
|
|
8
|
+
const _validateItemData = async () => {
|
|
9
|
+
if (context && context.localId) {
|
|
10
|
+
return true
|
|
11
|
+
}
|
|
12
|
+
return false
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
_validateItemData().then((isValid) => {
|
|
16
|
+
if (isValid) {
|
|
17
|
+
sendBack({ type: 'validateItemDataSuccess' })
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { versions } from '@/seedSchema'
|
|
2
|
+
import { count, max } from 'drizzle-orm'
|
|
3
|
+
import { BaseDb } from '@/db/Db/BaseDb'
|
|
4
|
+
|
|
5
|
+
export const getVersionData = () => {
|
|
6
|
+
const appDb = BaseDb.getAppDb()
|
|
7
|
+
|
|
8
|
+
return appDb.$with('versionData').as(
|
|
9
|
+
appDb
|
|
10
|
+
.select({
|
|
11
|
+
seedLocalId: versions.seedLocalId,
|
|
12
|
+
seedUid: versions.seedUid,
|
|
13
|
+
latestVersionUid: versions.uid,
|
|
14
|
+
latestVersionLocalId: versions.localId,
|
|
15
|
+
versionsCount: count(versions.localId).as('versionsCount'),
|
|
16
|
+
lastVersionPublishedAt: max(versions.attestationCreatedAt).as(
|
|
17
|
+
'lastVersionPublishedAt',
|
|
18
|
+
),
|
|
19
|
+
lastLocalUpdateAt: max(versions.createdAt).as('lastLocalUpdateAt'),
|
|
20
|
+
})
|
|
21
|
+
.from(versions)
|
|
22
|
+
.groupBy(versions.seedLocalId),
|
|
23
|
+
)
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EventObject, fromCallback } from 'xstate'
|
|
2
|
+
import { FromCallbackInput, PropertyMachineContext } from '@/types'
|
|
3
|
+
import { BaseDb } from '@/db/Db/BaseDb'
|
|
4
|
+
import debug from 'debug'
|
|
5
|
+
|
|
6
|
+
const logger = debug('app:ItemProperty:service:actors:waitForDb')
|
|
7
|
+
|
|
8
|
+
export const waitForDb = fromCallback<
|
|
9
|
+
EventObject,
|
|
10
|
+
FromCallbackInput<PropertyMachineContext>
|
|
11
|
+
>(({ sendBack }) => {
|
|
12
|
+
const _waitForDb = new Promise<void>((resolve) => {
|
|
13
|
+
const interval = setInterval(() => {
|
|
14
|
+
const appDb = BaseDb.getAppDb()
|
|
15
|
+
if (appDb) {
|
|
16
|
+
clearInterval(interval)
|
|
17
|
+
resolve()
|
|
18
|
+
}
|
|
19
|
+
}, 100)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
_waitForDb.then(() => {
|
|
23
|
+
sendBack({ type: 'waitForDbSuccess' })
|
|
24
|
+
})
|
|
25
|
+
})
|