@seedprotocol/sdk 0.7.3 → 0.7.4-next.784.g879c6a3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BasePathResolver-Cm4apKRb.js → BasePathResolver-DxdS0wJ0.js} +43 -8
- package/dist/BasePathResolver-DxdS0wJ0.js.map +1 -0
- package/dist/{ClientManager-i3nJASkg.js → ClientManager-De-vKHGe.js} +37 -38
- package/dist/ClientManager-De-vKHGe.js.map +1 -0
- package/dist/{Item-DBFchXpC.js → Item-cq9VcsAY.js} +365 -191
- package/dist/Item-cq9VcsAY.js.map +1 -0
- package/dist/{ModelProperty-BS49g01Y.js → ModelProperty-DuuoFXaC.js} +45 -37
- package/dist/ModelProperty-DuuoFXaC.js.map +1 -0
- package/dist/{Schema-CpMNEnUO.js → Schema-Dc5EA8Yb.js} +246 -68
- package/dist/Schema-Dc5EA8Yb.js.map +1 -0
- package/dist/{SchemaValidationService-DieV4KL-.js → SchemaValidationService-DViJ056F.js} +49 -36
- package/dist/SchemaValidationService-DViJ056F.js.map +1 -0
- package/dist/{backfillMetadataPropertyIds-DSoOoTnX.js → backfillMetadataPropertyIds-DacVthS5.js} +3 -3
- package/dist/{backfillMetadataPropertyIds-DSoOoTnX.js.map → backfillMetadataPropertyIds-DacVthS5.js.map} +1 -1
- package/dist/{configurePlatform-D0lQGAMQ.js → configurePlatform-DlZ23w7e.js} +2 -2
- package/dist/{configurePlatform-D0lQGAMQ.js.map → configurePlatform-DlZ23w7e.js.map} +1 -1
- package/dist/{detachRowsBeforeDelete-S0q-DJPT.js → detachRowsBeforeDelete-YRSZY6dO.js} +2 -2
- package/dist/{detachRowsBeforeDelete-S0q-DJPT.js.map → detachRowsBeforeDelete-YRSZY6dO.js.map} +1 -1
- package/dist/{eas-6pjU-OuX.js → eas-D_6ptL_F.js} +4 -4
- package/dist/{eas-6pjU-OuX.js.map → eas-D_6ptL_F.js.map} +1 -1
- package/dist/{index-8O3Uow-Y.js → errors-Cl8rbtKR.js} +192 -48
- package/dist/errors-Cl8rbtKR.js.map +1 -0
- package/dist/{getItem-CxBNZ-WL.js → getItem-BcmJcUZB.js} +5 -5
- package/dist/{getItem-CxBNZ-WL.js.map → getItem-BcmJcUZB.js.map} +1 -1
- package/dist/{getPublishPayload-CTCvRUoU.js → getPublishPayload-C278kK9P.js} +15 -15
- package/dist/{getPublishPayload-CTCvRUoU.js.map → getPublishPayload-C278kK9P.js.map} +1 -1
- package/dist/{getPublishUploads-SFHCbf_y.js → getPublishUploads-DJ1UPh7i.js} +9 -9
- package/dist/{getPublishUploads-SFHCbf_y.js.map → getPublishUploads-DJ1UPh7i.js.map} +1 -1
- package/dist/{index-Cvt5UBz4.js → index-CqnU-5i0.js} +9 -9
- package/dist/index-CqnU-5i0.js.map +1 -0
- package/dist/{index-AVFTVp1m.js → index-DAl9U4rn.js} +2 -2
- package/dist/index-DAl9U4rn.js.map +1 -0
- package/dist/{index.browser-DBhxRoe8.js → index.browser-J6QZ9smP.js} +10 -10
- package/dist/{index.browser-DBhxRoe8.js.map → index.browser-J6QZ9smP.js.map} +1 -1
- package/dist/{index.node-CJhlcNHM.js → index.node-C9VB9NlX.js} +9 -9
- package/dist/index.node-C9VB9NlX.js.map +1 -0
- package/dist/main.js +24 -24
- package/dist/{model-DGMe-TTm.js → model-oHA3YhOd.js} +5 -1
- package/dist/model-oHA3YhOd.js.map +1 -0
- package/dist/node.js +11 -11
- package/dist/node.js.map +1 -1
- package/dist/platform.browser.js +5 -5
- package/dist/platform.node.js +4 -4
- package/dist/{property-DwPD283A.js → property-Brgr5RdT.js} +11 -11
- package/dist/{property-DwPD283A.js.map → property-Brgr5RdT.js.map} +1 -1
- package/dist/propertyValidationRules-CDRitiiK.js +51 -0
- package/dist/propertyValidationRules-CDRitiiK.js.map +1 -0
- package/dist/{publishDraftGraph-BOn3_Occ.js → publishDraftGraph-C37ibxb5.js} +6 -6
- package/dist/{publishDraftGraph-BOn3_Occ.js.map → publishDraftGraph-C37ibxb5.js.map} +1 -1
- package/dist/{resetAmbiguousLegacyItemData-BkYmBeJc.js → resetAmbiguousLegacyItemData-CcLFRREE.js} +2 -2
- package/dist/{resetAmbiguousLegacyItemData-BkYmBeJc.js.map → resetAmbiguousLegacyItemData-CcLFRREE.js.map} +1 -1
- package/dist/{resolveModelForSyncedSeed-BL24nLa7.js → resolveModelForSyncedSeed-BTAeCOJE.js} +2 -2
- package/dist/{resolveModelForSyncedSeed-BL24nLa7.js.map → resolveModelForSyncedSeed-BTAeCOJE.js.map} +1 -1
- package/dist/src/Item/Item.d.ts +6 -2
- package/dist/src/Item/Item.d.ts.map +1 -1
- package/dist/src/Item/errors.d.ts +23 -0
- package/dist/src/Item/errors.d.ts.map +1 -0
- package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/hydrateFromDb.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/loadOrCreateProperty.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/analyzeInput.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveFile.d.ts +19 -0
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveFile.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveImage.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveItemStorage.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/propertyMachine.d.ts.map +1 -1
- package/dist/src/Model/Model.d.ts +2 -0
- package/dist/src/Model/Model.d.ts.map +1 -1
- package/dist/src/Model/service/actors/createModelProperties.d.ts.map +1 -1
- package/dist/src/ModelProperty/ModelProperty.d.ts +2 -0
- package/dist/src/ModelProperty/ModelProperty.d.ts.map +1 -1
- package/dist/src/Schema/Schema.d.ts +11 -2
- package/dist/src/Schema/Schema.d.ts.map +1 -1
- package/dist/src/Schema/service/actors/checkExistingSchema.d.ts.map +1 -1
- package/dist/src/Schema/service/actors/loadOrCreateSchema.d.ts.map +1 -1
- package/dist/src/Schema/service/schemaMachine.d.ts.map +1 -1
- package/dist/src/Schema/service/validation/SchemaValidationService.d.ts +4 -1
- package/dist/src/Schema/service/validation/SchemaValidationService.d.ts.map +1 -1
- package/dist/src/db/Db/BaseDb.d.ts +5 -2
- package/dist/src/db/Db/BaseDb.d.ts.map +1 -1
- package/dist/src/db/write/updateItemPropertyValue.d.ts.map +1 -1
- package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
- package/dist/src/helpers/db.d.ts.map +1 -1
- package/dist/src/helpers/entity/draftSaveErrors.d.ts +4 -0
- package/dist/src/helpers/entity/draftSaveErrors.d.ts.map +1 -0
- package/dist/src/helpers/entity/entityUnload.d.ts +2 -1
- package/dist/src/helpers/entity/entityUnload.d.ts.map +1 -1
- package/dist/src/helpers/entity/evictionEpoch.d.ts +27 -2
- package/dist/src/helpers/entity/evictionEpoch.d.ts.map +1 -1
- package/dist/src/helpers/isSqliteUniqueConstraintError.d.ts.map +1 -1
- package/dist/src/helpers/model.d.ts.map +1 -1
- package/dist/src/helpers/propertyValidationRules.d.ts +12 -0
- package/dist/src/helpers/propertyValidationRules.d.ts.map +1 -0
- package/dist/src/helpers/propertyWriteQueue.d.ts +15 -0
- package/dist/src/helpers/propertyWriteQueue.d.ts.map +1 -0
- package/dist/src/helpers/schema.d.ts.map +1 -1
- package/dist/src/helpers/storageFileName.d.ts +7 -0
- package/dist/src/helpers/storageFileName.d.ts.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/node/db/Db.d.ts +1 -1
- package/dist/src/node/db/Db.d.ts.map +1 -1
- package/dist/src/node/index.d.ts +1 -0
- package/dist/src/node/index.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +12 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/{syncDbWithEas-Bv2Fe38J.js → syncDbWithEas-B-Ho0IOB.js} +50 -27
- package/dist/syncDbWithEas-B-Ho0IOB.js.map +1 -0
- package/dist/{tabEvents-9s2WCYw-.js → tabEvents-BTzckWrN.js} +4 -4
- package/dist/{tabEvents-9s2WCYw-.js.map → tabEvents-BTzckWrN.js.map} +1 -1
- package/dist/{tolerantWebAccess-iUu80pAP.js → tolerantWebAccess-DOm2Xv-f.js} +6 -6
- package/dist/{tolerantWebAccess-iUu80pAP.js.map → tolerantWebAccess-DOm2Xv-f.js.map} +1 -1
- package/dist/{updateSeedRevokedAt-zBfi931j.js → updateSeedRevokedAt-IHXnJI-i.js} +3 -3
- package/dist/{updateSeedRevokedAt-zBfi931j.js.map → updateSeedRevokedAt-IHXnJI-i.js.map} +1 -1
- package/package.json +5 -5
- package/dist/BasePathResolver-Cm4apKRb.js.map +0 -1
- package/dist/ClientManager-i3nJASkg.js.map +0 -1
- package/dist/Item-DBFchXpC.js.map +0 -1
- package/dist/ModelProperty-BS49g01Y.js.map +0 -1
- package/dist/Schema-CpMNEnUO.js.map +0 -1
- package/dist/SchemaValidationService-DieV4KL-.js.map +0 -1
- package/dist/index-8O3Uow-Y.js.map +0 -1
- package/dist/index-AVFTVp1m.js.map +0 -1
- package/dist/index-Cvt5UBz4.js.map +0 -1
- package/dist/index.node-CJhlcNHM.js.map +0 -1
- package/dist/model-DGMe-TTm.js.map +0 -1
- package/dist/syncDbWithEas-Bv2Fe38J.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { waitFor, fromCallback, setup, assign, stateIn, createActor, isMachineSnapshot } from 'xstate';
|
|
2
|
-
import { n as normalizeDataType, E as BaseDb, C as versions, m as metadata, A as seeds, z as schemas, s as models, q as modelSchemas, aQ as getOwnedAddressesFromDb, a9 as ZERO_BYTES32, aB as normalizeAddressList, a0 as normalizeHexAddress, ay as getAddressesForItemsFilter, H as toSnakeCase$1, ad as INTERNAL_PROPERTY_NAMES, J as BaseFileManager, aS as getStorageTransactionIdForSeedUid, aT as convertTxIdToImage, i as isDataType, X as normalizePublisher, ax as ensureImageLocal, ap as ImageSize, aU as downloadTransactionIdWithDedupe, u as properties, M as ModelPropertyDataTypes, $ as generateId, ag as INTERNAL_DATA_TYPES, r as modelUids, L as resolveItemModelFileId, aV as getPropertyIdForSchemaFileId, K as getPropertyIdForModelAndName, aW as getDataTypeFromString, aX as getMimeType, am as INTERNAL_STORAGE_MODEL_FILE_IDS, V as getItemStorageSubdir, W as getItemStorageLocalFileName, g as normalizePropertyRecordSchema, aY as PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP, a5 as getCorrectId, G as eventEmitter, ae as isStorageSeedRef } from './BasePathResolver-
|
|
2
|
+
import { n as normalizeDataType, E as BaseDb, C as versions, m as metadata, A as seeds, z as schemas, s as models, q as modelSchemas, aQ as getOwnedAddressesFromDb, a9 as ZERO_BYTES32, aB as normalizeAddressList, a0 as normalizeHexAddress, ay as getAddressesForItemsFilter, H as toSnakeCase$1, ad as INTERNAL_PROPERTY_NAMES, J as BaseFileManager, aS as getStorageTransactionIdForSeedUid, aT as convertTxIdToImage, i as isDataType, X as normalizePublisher, ax as ensureImageLocal, ap as ImageSize, aU as downloadTransactionIdWithDedupe, u as properties, M as ModelPropertyDataTypes, $ as generateId, ag as INTERNAL_DATA_TYPES, r as modelUids, L as resolveItemModelFileId, aV as getPropertyIdForSchemaFileId, K as getPropertyIdForModelAndName, aW as getDataTypeFromString, aX as getMimeType, am as INTERNAL_STORAGE_MODEL_FILE_IDS, V as getItemStorageSubdir, W as getItemStorageLocalFileName, g as normalizePropertyRecordSchema, aY as PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP, a5 as getCorrectId, G as eventEmitter, ae as isStorageSeedRef } from './BasePathResolver-DxdS0wJ0.js';
|
|
3
3
|
import { or, isNull, eq, max, count, and, getTableColumns, sql, desc, inArray, isNotNull, gt } from 'drizzle-orm';
|
|
4
4
|
import pluralize from 'pluralize';
|
|
5
5
|
import debug from 'debug';
|
|
@@ -8,8 +8,8 @@ import { startCase, upperFirst, camelCase, orderBy } from 'lodash-es';
|
|
|
8
8
|
import { toSnakeCase } from 'drizzle-orm/casing';
|
|
9
9
|
import { isValidEasAttestationUid, isPlaceholderUid, BaseQueryClient, BaseEasClient, GET_SCHEMAS, getEasSchemaUidForSchemaDefinition, getSchemaUidForModelFromCache, cachedSchemaLookup, setSchemaUidForModel, getEasSchemaUidForExactDefinition } from '@seedprotocol/eas';
|
|
10
10
|
import { fetchArweaveRawTextAcrossGateways } from '@seedprotocol/arweave';
|
|
11
|
-
import { d as notifyFileSaved, f as withTabLock } from './tabEvents-
|
|
12
|
-
import { modelPropertiesToObject } from './model-
|
|
11
|
+
import { d as notifyFileSaved, f as withTabLock } from './tabEvents-BTzckWrN.js';
|
|
12
|
+
import { modelPropertiesToObject } from './model-oHA3YhOd.js';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Default readyTimeout for create/find/all with waitForReady. Loads that touch OPFS and the DB can take
|
|
@@ -724,9 +724,9 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
724
724
|
try {
|
|
725
725
|
const itemPropertyMod = await Promise.resolve().then(function () { return ItemProperty$1; });
|
|
726
726
|
const { ItemProperty } = itemPropertyMod;
|
|
727
|
-
const { modelPropertiesToObject } = await import('./model-
|
|
728
|
-
const _mod_0 = await import('./
|
|
729
|
-
const _ns_0 = _mod_0.
|
|
727
|
+
const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
|
|
728
|
+
const _mod_0 = await import('./errors-Cl8rbtKR.js');
|
|
729
|
+
const _ns_0 = _mod_0.h;
|
|
730
730
|
const { Model } = _ns_0;
|
|
731
731
|
// Resolve Model and build property schemas (use getByNameAsync for models not yet in cache)
|
|
732
732
|
let propertySchemas = {};
|
|
@@ -743,7 +743,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
743
743
|
const schemaNameToTry = schemaName ?? model?.schemaName;
|
|
744
744
|
if (schemaNameToTry) {
|
|
745
745
|
try {
|
|
746
|
-
const _mod_1 = await import('./Schema-
|
|
746
|
+
const _mod_1 = await import('./Schema-Dc5EA8Yb.js');
|
|
747
747
|
const _ns_1 = _mod_1.b;
|
|
748
748
|
const { Schema } = _ns_1;
|
|
749
749
|
const schemaInstance = Schema.create(schemaNameToTry, { waitForReady: false });
|
|
@@ -759,7 +759,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
759
759
|
}
|
|
760
760
|
if (Object.keys(propertySchemas).length === 0) {
|
|
761
761
|
try {
|
|
762
|
-
const _mod_2 = await import('./ClientManager-
|
|
762
|
+
const _mod_2 = await import('./ClientManager-De-vKHGe.js');
|
|
763
763
|
const _ns_2 = _mod_2.K;
|
|
764
764
|
const { loadAllSchemasFromDb } = _ns_2;
|
|
765
765
|
const allSchemas = await loadAllSchemasFromDb();
|
|
@@ -780,11 +780,11 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
780
780
|
}
|
|
781
781
|
if (Object.keys(propertySchemas).length === 0) {
|
|
782
782
|
try {
|
|
783
|
-
const _mod_3 = await import('./ClientManager-
|
|
783
|
+
const _mod_3 = await import('./ClientManager-De-vKHGe.js');
|
|
784
784
|
const _ns_3 = _mod_3.K;
|
|
785
785
|
const { listCompleteSchemaFiles } = _ns_3;
|
|
786
|
-
const _mod_4 = await import('./BasePathResolver-
|
|
787
|
-
const _ns_4 = _mod_4.
|
|
786
|
+
const _mod_4 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
787
|
+
const _ns_4 = _mod_4.a$;
|
|
788
788
|
const { BaseFileManager } = _ns_4;
|
|
789
789
|
const schemaFiles = await listCompleteSchemaFiles();
|
|
790
790
|
for (const { filePath } of schemaFiles) {
|
|
@@ -804,7 +804,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
804
804
|
}
|
|
805
805
|
}
|
|
806
806
|
if (Object.keys(propertySchemas).length === 0) {
|
|
807
|
-
const schemaMod = await import('./index-
|
|
807
|
+
const schemaMod = await import('./index-CqnU-5i0.js');
|
|
808
808
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
809
809
|
const KNOWN_MODEL_FALLBACKS = {
|
|
810
810
|
Post: {
|
|
@@ -821,7 +821,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
821
821
|
}
|
|
822
822
|
}
|
|
823
823
|
// Fallbacks above may return schema-file shape ({ type, model, items }); normalize to dataType/ref/refValueType.
|
|
824
|
-
const { normalizePropertyRecordSchema } = await import('./property-
|
|
824
|
+
const { normalizePropertyRecordSchema } = await import('./property-Brgr5RdT.js');
|
|
825
825
|
propertySchemas = Object.fromEntries(Object.entries(propertySchemas).map(([name, def]) => [name, normalizePropertyRecordSchema(def)]));
|
|
826
826
|
// Collapse rows that map to the same instance key (e.g. authorIdentityIds + authors -> authors).
|
|
827
827
|
// ItemProperty.create cache does not sync propertyValue on hit; processing order would otherwise
|
|
@@ -854,7 +854,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
854
854
|
// Infer propertyRecordSchema from metadata when schema is missing (enables persistence)
|
|
855
855
|
let propSchema = propertySchemas[propertyName];
|
|
856
856
|
if (!propSchema && isRefTypeFromMeta) {
|
|
857
|
-
const schemaMod = await import('./index-
|
|
857
|
+
const schemaMod = await import('./index-CqnU-5i0.js');
|
|
858
858
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
859
859
|
propSchema = {
|
|
860
860
|
dataType: refSeedType === 'html' ? ModelPropertyDataTypes.Html
|
|
@@ -1860,8 +1860,8 @@ const getItemsData = async ({ modelName, modelFileId, schemaName, deleted, inclu
|
|
|
1860
1860
|
conditions.push(eq(seeds.type, toSnakeCase(modelName)));
|
|
1861
1861
|
}
|
|
1862
1862
|
if (!modelFileId && schemaName && modelName) {
|
|
1863
|
-
const _mod_5 = await import('./BasePathResolver-
|
|
1864
|
-
const _ns_5 = _mod_5.
|
|
1863
|
+
const _mod_5 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
1864
|
+
const _ns_5 = _mod_5.b2;
|
|
1865
1865
|
const { resolveModelRecord } = _ns_5;
|
|
1866
1866
|
modelFileId = (await resolveModelRecord(modelName, { schemaName }))?.schemaFileId ?? undefined;
|
|
1867
1867
|
if (!modelFileId)
|
|
@@ -2143,7 +2143,7 @@ const resolveRelatedValue = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
2143
2143
|
const { isRelation, propertyValue, propertyName, seedUid, propertyRecordSchema, populatedFromDb, schemaUid, } = context;
|
|
2144
2144
|
const _resolveRelatedValue = async () => {
|
|
2145
2145
|
// Use dynamic import to break circular dependency
|
|
2146
|
-
const schemaMod = await import('./index-
|
|
2146
|
+
const schemaMod = await import('./index-CqnU-5i0.js');
|
|
2147
2147
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
2148
2148
|
if (!propertyValue || !isRelation || populatedFromDb) {
|
|
2149
2149
|
return;
|
|
@@ -2578,8 +2578,8 @@ async function readHtmlBodyFromChildStorageArweave(seedLocalId) {
|
|
|
2578
2578
|
/* offline / bad tx id */
|
|
2579
2579
|
}
|
|
2580
2580
|
try {
|
|
2581
|
-
const _mod_6 = await import('./BasePathResolver-
|
|
2582
|
-
const _ns_6 = _mod_6.
|
|
2581
|
+
const _mod_6 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
2582
|
+
const _ns_6 = _mod_6.b4;
|
|
2583
2583
|
const { downloadTransactionIdWithDedupe } = _ns_6;
|
|
2584
2584
|
await downloadTransactionIdWithDedupe(txId);
|
|
2585
2585
|
const retryFp = BaseFileManager.getFilesPath('html', `${seedLocalId}.html`);
|
|
@@ -2639,7 +2639,7 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
2639
2639
|
// to use dynamically imported ModelPropertyDataTypes
|
|
2640
2640
|
const _hydrateFromDb = async () => {
|
|
2641
2641
|
// Use dynamic import to break circular dependency
|
|
2642
|
-
const schemaMod = await import('./index-
|
|
2642
|
+
const schemaMod = await import('./index-CqnU-5i0.js');
|
|
2643
2643
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
2644
2644
|
const appDb = BaseDb.getAppDb();
|
|
2645
2645
|
const whereClauses = [];
|
|
@@ -2772,7 +2772,9 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
2772
2772
|
}
|
|
2773
2773
|
if (filePath) {
|
|
2774
2774
|
localStorageDir = `/${dir}`;
|
|
2775
|
-
|
|
2775
|
+
// The same content URL saveFile sets, so the value reads the same before and after a reload.
|
|
2776
|
+
refResolvedDisplayValue = await BaseFileManager.getContentUrlFromPath(filePath);
|
|
2777
|
+
renderValue = refResolvedDisplayValue;
|
|
2776
2778
|
}
|
|
2777
2779
|
}
|
|
2778
2780
|
catch (e) {
|
|
@@ -2918,12 +2920,12 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
|
|
|
2918
2920
|
const modelNameForNew = context.modelName;
|
|
2919
2921
|
if (modelNameForNew) {
|
|
2920
2922
|
try {
|
|
2921
|
-
const _mod_7 = await import('./
|
|
2922
|
-
const _ns_7 = _mod_7.
|
|
2923
|
+
const _mod_7 = await import('./errors-Cl8rbtKR.js');
|
|
2924
|
+
const _ns_7 = _mod_7.h;
|
|
2923
2925
|
const { Model } = _ns_7;
|
|
2924
|
-
const { modelPropertiesToObject } = await import('./model-
|
|
2925
|
-
const _mod_8 = await import('./BasePathResolver-
|
|
2926
|
-
const _ns_8 = _mod_8.
|
|
2926
|
+
const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
|
|
2927
|
+
const _mod_8 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
2928
|
+
const _ns_8 = _mod_8.b2;
|
|
2927
2929
|
const { resolveItemModelFileId } = _ns_8;
|
|
2928
2930
|
const normalizedModelName = upperFirst(camelCase(modelNameForNew));
|
|
2929
2931
|
const itemModelFileId = await resolveItemModelFileId({
|
|
@@ -2976,8 +2978,8 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
|
|
|
2976
2978
|
// It ends up in the context below, and later lookups by name (Model.getByName) can't match it.
|
|
2977
2979
|
const modelName = context.modelName || (metadataRecord.modelType ? upperFirst(camelCase(metadataRecord.modelType)) : undefined);
|
|
2978
2980
|
// Model names are only unique per schema: pin lookups to the item's own model row.
|
|
2979
|
-
const _mod_9 = await import('./BasePathResolver-
|
|
2980
|
-
const _ns_9 = _mod_9.
|
|
2981
|
+
const _mod_9 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
2982
|
+
const _ns_9 = _mod_9.b2;
|
|
2981
2983
|
const { resolveItemModelFileId, resolveModelRecord } = _ns_9;
|
|
2982
2984
|
const modelFileId = await resolveItemModelFileId({
|
|
2983
2985
|
modelFileId: context.modelFileId,
|
|
@@ -3020,47 +3022,13 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
|
|
|
3020
3022
|
filenameSuffix: propRecord.filenameSuffix || undefined,
|
|
3021
3023
|
required: propRecord.required ?? undefined,
|
|
3022
3024
|
};
|
|
3023
|
-
//
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
// Fallback: get validation from schemaData in database (Schema context may not be loaded yet)
|
|
3031
|
-
const _mod_10 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
3032
|
-
const _ns_10 = _mod_10.a$;
|
|
3033
|
-
const { schemas: schemasTable } = _ns_10;
|
|
3034
|
-
const _mod_11 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
3035
|
-
const _ns_11 = _mod_11.b0;
|
|
3036
|
-
const { modelSchemas } = _ns_11;
|
|
3037
|
-
const modelSchemaRows = await db
|
|
3038
|
-
.select({ schemaId: modelSchemas.schemaId })
|
|
3039
|
-
.from(modelSchemas)
|
|
3040
|
-
.where(eq(modelSchemas.modelId, modelRecords[0].id))
|
|
3041
|
-
.limit(1);
|
|
3042
|
-
if (modelSchemaRows.length > 0 && modelSchemaRows[0].schemaId) {
|
|
3043
|
-
const schemaRows = await db
|
|
3044
|
-
.select({ schemaData: schemasTable.schemaData })
|
|
3045
|
-
.from(schemasTable)
|
|
3046
|
-
.where(eq(schemasTable.id, modelSchemaRows[0].schemaId))
|
|
3047
|
-
.limit(1);
|
|
3048
|
-
if (schemaRows.length > 0 && schemaRows[0].schemaData) {
|
|
3049
|
-
const parsed = JSON.parse(schemaRows[0].schemaData);
|
|
3050
|
-
const modelDef = parsed?.models?.[normalizedModelName];
|
|
3051
|
-
const propDef = modelDef?.properties?.[propertyName];
|
|
3052
|
-
if (propDef?.validation) {
|
|
3053
|
-
propertyRecordSchema = { ...propertyRecordSchema, validation: propDef.validation };
|
|
3054
|
-
}
|
|
3055
|
-
}
|
|
3056
|
-
}
|
|
3057
|
-
}
|
|
3058
|
-
else {
|
|
3059
|
-
propertyRecordSchema = { ...propertyRecordSchema, validation: schemaFromFile.validation };
|
|
3060
|
-
}
|
|
3061
|
-
}
|
|
3062
|
-
catch {
|
|
3063
|
-
// Schema not loaded or lookup failed - continue with DB schema only
|
|
3025
|
+
// Validation rules (enum, pattern, ...) aren't in the properties table
|
|
3026
|
+
const { resolvePropertyValidationRules } = await import('./propertyValidationRules-CDRitiiK.js');
|
|
3027
|
+
const validation = await resolvePropertyValidationRules(normalizedModelName, propertyName, {
|
|
3028
|
+
modelFileId: modelRecord?.schemaFileId ?? modelFileId,
|
|
3029
|
+
});
|
|
3030
|
+
if (validation) {
|
|
3031
|
+
propertyRecordSchema = { ...propertyRecordSchema, validation };
|
|
3064
3032
|
}
|
|
3065
3033
|
}
|
|
3066
3034
|
}
|
|
@@ -3072,10 +3040,10 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
|
|
|
3072
3040
|
}
|
|
3073
3041
|
if (!propertyRecordSchema && modelName) {
|
|
3074
3042
|
try {
|
|
3075
|
-
const
|
|
3076
|
-
const
|
|
3077
|
-
const { Model } =
|
|
3078
|
-
const { modelPropertiesToObject } = await import('./model-
|
|
3043
|
+
const _mod_10 = await import('./errors-Cl8rbtKR.js');
|
|
3044
|
+
const _ns_10 = _mod_10.h;
|
|
3045
|
+
const { Model } = _ns_10;
|
|
3046
|
+
const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
|
|
3079
3047
|
const normalizedModelName = upperFirst(camelCase(modelName));
|
|
3080
3048
|
// Try PascalCase first ("post" -> "Post"); then findByModelType for names with spaces ("new_model" -> "New model")
|
|
3081
3049
|
let model = Model.resolve(normalizedModelName, { modelFileId });
|
|
@@ -3226,7 +3194,8 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
|
|
|
3226
3194
|
filePath = await resolveMatchingFilePath(dir, metadataRecord.refResolvedValue);
|
|
3227
3195
|
}
|
|
3228
3196
|
if (filePath) {
|
|
3229
|
-
|
|
3197
|
+
// The content URL saveFile and hydrateFromDb set, so the value reads the same everywhere.
|
|
3198
|
+
renderValue = await BaseFileManager.getContentUrlFromPath(filePath);
|
|
3230
3199
|
}
|
|
3231
3200
|
}
|
|
3232
3201
|
catch (e) {
|
|
@@ -3356,12 +3325,16 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
|
|
|
3356
3325
|
if (localId == null)
|
|
3357
3326
|
return;
|
|
3358
3327
|
// Use Drizzle update API for proper parameterization (avoids SQL injection from filenames with quotes)
|
|
3328
|
+
const now = Date.now();
|
|
3359
3329
|
const updatePayload = {
|
|
3360
3330
|
propertyValue: safeNewValue ?? null,
|
|
3361
3331
|
refSeedType: refSeedType ?? null,
|
|
3362
3332
|
refResolvedValue: refResolvedValue ?? null,
|
|
3363
3333
|
refResolvedDisplayValue: refResolvedDisplayValue ?? null,
|
|
3364
|
-
|
|
3334
|
+
// Readers take the newest row by COALESCE(attestation_created_at, created_at), so a draft's
|
|
3335
|
+
// time is when its value was last set: a synced value older than this edit mustn't win.
|
|
3336
|
+
createdAt: now,
|
|
3337
|
+
updatedAt: now,
|
|
3365
3338
|
};
|
|
3366
3339
|
if (localStorageDir !== undefined) {
|
|
3367
3340
|
updatePayload.localStorageDir = localStorageDir ?? null;
|
|
@@ -3434,6 +3407,48 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
|
|
|
3434
3407
|
};
|
|
3435
3408
|
};
|
|
3436
3409
|
|
|
3410
|
+
const queues = new Map();
|
|
3411
|
+
let nextTicket = 0;
|
|
3412
|
+
const propertyWriteKey = (seedId, propertyName) => (seedId && propertyName ? `${seedId}:${propertyName}` : undefined);
|
|
3413
|
+
const reservePropertyWrite = (key) => {
|
|
3414
|
+
let queue = queues.get(key);
|
|
3415
|
+
if (!queue) {
|
|
3416
|
+
queue = { tail: Promise.resolve(), latest: 0, pending: 0 };
|
|
3417
|
+
queues.set(key, queue);
|
|
3418
|
+
}
|
|
3419
|
+
const q = queue;
|
|
3420
|
+
const ticket = ++nextTicket;
|
|
3421
|
+
q.latest = ticket;
|
|
3422
|
+
q.pending += 1;
|
|
3423
|
+
let released = false;
|
|
3424
|
+
const release = () => {
|
|
3425
|
+
if (released)
|
|
3426
|
+
return;
|
|
3427
|
+
released = true;
|
|
3428
|
+
q.pending -= 1;
|
|
3429
|
+
if (q.pending === 0 && queues.get(key) === q)
|
|
3430
|
+
queues.delete(key);
|
|
3431
|
+
};
|
|
3432
|
+
const run = async (write) => {
|
|
3433
|
+
const previous = q.tail;
|
|
3434
|
+
let done;
|
|
3435
|
+
const mine = new Promise((resolve) => (done = resolve));
|
|
3436
|
+
q.tail = previous.then(() => mine);
|
|
3437
|
+
try {
|
|
3438
|
+
await previous;
|
|
3439
|
+
if (q.latest !== ticket)
|
|
3440
|
+
return { skipped: true };
|
|
3441
|
+
return { skipped: false, result: await write() };
|
|
3442
|
+
}
|
|
3443
|
+
finally {
|
|
3444
|
+
done();
|
|
3445
|
+
release();
|
|
3446
|
+
}
|
|
3447
|
+
};
|
|
3448
|
+
return { run, release };
|
|
3449
|
+
};
|
|
3450
|
+
const hasPendingPropertyWrite = (key) => !!key && (queues.get(key)?.pending ?? 0) > 0;
|
|
3451
|
+
|
|
3437
3452
|
const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
3438
3453
|
const { localId, propertyName: propertyNameRaw, seedLocalId, versionLocalId, versionUid, propertyValue: existingValue, propertyRecordSchema, modelName, } = context;
|
|
3439
3454
|
let { schemaUid } = context;
|
|
@@ -3447,6 +3462,10 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3447
3462
|
if (!propertyRecordSchema) {
|
|
3448
3463
|
throw new Error('Missing propertyRecordSchema');
|
|
3449
3464
|
}
|
|
3465
|
+
// Reserved now, before the async checks below, so a newer save always replaces this one.
|
|
3466
|
+
const writeKey = propertyWriteKey(seedLocalId ?? context.seedUid, propertyNameRaw);
|
|
3467
|
+
const writeSlot = writeKey ? reservePropertyWrite(writeKey) : undefined;
|
|
3468
|
+
const writeValue = (write) => writeSlot ? writeSlot.run(write) : write().then((result) => ({ skipped: false, result }));
|
|
3450
3469
|
const _analyzeInput = async () => {
|
|
3451
3470
|
// Assignment writes straight to the DB, so check ownership here as save()/destroy()/publish() do.
|
|
3452
3471
|
const { isItemOwned, OwnershipError } = await Promise.resolve().then(function () { return ownership; });
|
|
@@ -3455,9 +3474,9 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3455
3474
|
return false;
|
|
3456
3475
|
}
|
|
3457
3476
|
// Use dynamic import to break circular dependency
|
|
3458
|
-
const schemaMod = await import('./index-
|
|
3477
|
+
const schemaMod = await import('./index-CqnU-5i0.js');
|
|
3459
3478
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
3460
|
-
const { SchemaValidationService } = await import('./SchemaValidationService-
|
|
3479
|
+
const { SchemaValidationService } = await import('./SchemaValidationService-DViJ056F.js');
|
|
3461
3480
|
let propertyName = propertyNameRaw;
|
|
3462
3481
|
if (!propertyName) {
|
|
3463
3482
|
throw new Error('propertyName is required');
|
|
@@ -3541,7 +3560,7 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3541
3560
|
// List (including list of relations / primitives): JSON in DB, array in context for publish (bytes32[])
|
|
3542
3561
|
if (normalizedDataType === ModelPropertyDataTypes.List && Array.isArray(newValue)) {
|
|
3543
3562
|
const stringValue = JSON.stringify(newValue);
|
|
3544
|
-
const
|
|
3563
|
+
const written = await writeValue(() => updateItemPropertyValue({
|
|
3545
3564
|
localId,
|
|
3546
3565
|
propertyName: propertyName,
|
|
3547
3566
|
newValue: stringValue,
|
|
@@ -3552,7 +3571,11 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3552
3571
|
schemaUid,
|
|
3553
3572
|
dataType: propertyRecordSchema.dataType,
|
|
3554
3573
|
refValueType: propertyRecordSchema.refValueType,
|
|
3555
|
-
});
|
|
3574
|
+
}));
|
|
3575
|
+
// A newer save replaced this one: it writes, and sets the context, instead.
|
|
3576
|
+
if (written.skipped)
|
|
3577
|
+
return true;
|
|
3578
|
+
const result = written.result;
|
|
3556
3579
|
const updatedContext = {
|
|
3557
3580
|
propertyValue: newValue,
|
|
3558
3581
|
renderValue: newValue,
|
|
@@ -3572,7 +3595,7 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3572
3595
|
const stringValue = newValue !== null && newValue !== undefined
|
|
3573
3596
|
? (typeof newValue === 'string' ? newValue : String(newValue))
|
|
3574
3597
|
: null;
|
|
3575
|
-
const
|
|
3598
|
+
const written = await writeValue(() => updateItemPropertyValue({
|
|
3576
3599
|
localId,
|
|
3577
3600
|
propertyName: propertyName,
|
|
3578
3601
|
newValue: stringValue,
|
|
@@ -3583,7 +3606,10 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3583
3606
|
schemaUid,
|
|
3584
3607
|
dataType: propertyRecordSchema.dataType,
|
|
3585
3608
|
refValueType: propertyRecordSchema.refValueType,
|
|
3586
|
-
}); // Type assertion needed because newValue is not in MetadataType but is accepted by the function
|
|
3609
|
+
})); // Type assertion needed because newValue is not in MetadataType but is accepted by the function
|
|
3610
|
+
if (written.skipped)
|
|
3611
|
+
return true;
|
|
3612
|
+
const result = written.result;
|
|
3587
3613
|
const stringValueForContext = typeof newValue === 'string' ? newValue : (newValue !== null && newValue !== undefined ? String(newValue) : undefined);
|
|
3588
3614
|
let updatedContext = {
|
|
3589
3615
|
propertyValue: stringValueForContext,
|
|
@@ -3607,7 +3633,7 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3607
3633
|
});
|
|
3608
3634
|
return true;
|
|
3609
3635
|
};
|
|
3610
|
-
_analyzeInput().then((isDone) => {
|
|
3636
|
+
_analyzeInput().finally(() => writeSlot?.release()).then((isDone) => {
|
|
3611
3637
|
if (isDone) {
|
|
3612
3638
|
sendBack({ type: 'saveValueToDbSuccess' });
|
|
3613
3639
|
}
|
|
@@ -3749,7 +3775,7 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
|
|
|
3749
3775
|
propertyRecordSchema?.validation &&
|
|
3750
3776
|
metadataValues.propertyValue != null &&
|
|
3751
3777
|
metadataValues.propertyValue !== '') {
|
|
3752
|
-
const { SchemaValidationService } = await import('./SchemaValidationService-
|
|
3778
|
+
const { SchemaValidationService } = await import('./SchemaValidationService-DViJ056F.js');
|
|
3753
3779
|
const validationService = new SchemaValidationService();
|
|
3754
3780
|
const validationResult = validationService.validatePropertyValue(metadataValues.propertyValue, normalizeDataType(propertyRecordSchema.dataType), propertyRecordSchema.validation, propertyRecordSchema.refValueType
|
|
3755
3781
|
? normalizeDataType(String(propertyRecordSchema.refValueType))
|
|
@@ -3839,6 +3865,13 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
|
|
|
3839
3865
|
return inserted[0];
|
|
3840
3866
|
};
|
|
3841
3867
|
|
|
3868
|
+
/**
|
|
3869
|
+
* Name of a new Image or File seed's file in the shared `images/` or `files/` folder. Uploads keep
|
|
3870
|
+
* their own name (and so their extension, which publish reads for the content type), prefixed with
|
|
3871
|
+
* the new seed's local id: two posts that each upload `photo.png` mustn't write the same file.
|
|
3872
|
+
*/
|
|
3873
|
+
const storageFileNameForNewSeed = (seedLocalId, name) => `${seedLocalId}-${name}`;
|
|
3874
|
+
|
|
3842
3875
|
/** Fetch image from URL (including blob:) and return { buffer, mimeType } for saving as binary. */
|
|
3843
3876
|
const fetchImageAsBuffer = async (url) => {
|
|
3844
3877
|
const response = await fetch(url);
|
|
@@ -3922,6 +3955,9 @@ const saveImage = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3922
3955
|
fileName += `.${mimeType.split('/')[1]}`;
|
|
3923
3956
|
}
|
|
3924
3957
|
}
|
|
3958
|
+
else if (!isExistingFileReference) {
|
|
3959
|
+
fileName = storageFileNameForNewSeed(newImageSeedLocalId, fileName);
|
|
3960
|
+
}
|
|
3925
3961
|
const filePath = BaseFileManager.getFilesPath('images', fileName);
|
|
3926
3962
|
await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath('images'));
|
|
3927
3963
|
await createVersion({
|
|
@@ -4035,6 +4071,35 @@ const saveImage = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
4035
4071
|
});
|
|
4036
4072
|
|
|
4037
4073
|
let fileSchemaUid;
|
|
4074
|
+
/**
|
|
4075
|
+
* What a string assigned to a File property means:
|
|
4076
|
+
* - `data:` URL: its decoded bytes
|
|
4077
|
+
* - `http(s):` or `blob:` URL: fetched
|
|
4078
|
+
* - the name of a file already in the files folder: a reference to it
|
|
4079
|
+
* - anything else: the file's text content
|
|
4080
|
+
* (Bare strings used to be decoded as base64 when they looked like it, so "hello" became
|
|
4081
|
+
* garbage, and names like "photo.jpg" were fetched as URLs.)
|
|
4082
|
+
*/
|
|
4083
|
+
async function classifyFileString(value) {
|
|
4084
|
+
const dataUrl = /^data:([^,]*?)(;base64)?,(.*)$/s.exec(value);
|
|
4085
|
+
if (dataUrl) {
|
|
4086
|
+
const [, , isBase64, payload] = dataUrl;
|
|
4087
|
+
const bytes = isBase64
|
|
4088
|
+
? Uint8Array.from(atob(payload), (c) => c.charCodeAt(0))
|
|
4089
|
+
: new TextEncoder().encode(decodeURIComponent(payload));
|
|
4090
|
+
return { kind: 'dataUrl', bytes: bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) };
|
|
4091
|
+
}
|
|
4092
|
+
if (/^(https?:\/\/|blob:)/i.test(value)) {
|
|
4093
|
+
return { kind: 'url' };
|
|
4094
|
+
}
|
|
4095
|
+
if (!/[\\/]/.test(value) && value.length < 256) {
|
|
4096
|
+
const existingFilePath = BaseFileManager.getFilesPath('files', value);
|
|
4097
|
+
if (await BaseFileManager.pathExists(existingFilePath)) {
|
|
4098
|
+
return { kind: 'existing' };
|
|
4099
|
+
}
|
|
4100
|
+
}
|
|
4101
|
+
return { kind: 'text' };
|
|
4102
|
+
}
|
|
4038
4103
|
const saveFile = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
4039
4104
|
const { localId, propertyName: propertyNameRaw, propertyValue: existingValue, propertyRecordSchema, modelName, seedLocalId, seedUid, versionLocalId, versionUid, } = context;
|
|
4040
4105
|
let { schemaUid } = context;
|
|
@@ -4074,22 +4139,22 @@ const saveFile = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
4074
4139
|
const fetchedSchemaUid = await getEasSchemaUidForModel('File');
|
|
4075
4140
|
fileSchemaUid = fetchedSchemaUid ?? undefined;
|
|
4076
4141
|
}
|
|
4142
|
+
let isExistingFileReference = false;
|
|
4077
4143
|
if (typeof newValue === 'string') {
|
|
4078
|
-
const
|
|
4079
|
-
if (
|
|
4080
|
-
|
|
4081
|
-
const binaryString = atob(base64Data);
|
|
4082
|
-
const binaryArray = new Uint8Array(binaryString.length);
|
|
4083
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
4084
|
-
binaryArray[i] = binaryString.charCodeAt(i);
|
|
4085
|
-
}
|
|
4086
|
-
fileData = binaryArray.buffer;
|
|
4144
|
+
const source = await classifyFileString(newValue);
|
|
4145
|
+
if (source.kind === 'dataUrl') {
|
|
4146
|
+
fileData = source.bytes;
|
|
4087
4147
|
}
|
|
4088
|
-
else if (
|
|
4148
|
+
else if (source.kind === 'url') {
|
|
4089
4149
|
const response = await fetch(newValue);
|
|
4090
4150
|
fileData = await response.arrayBuffer();
|
|
4091
|
-
|
|
4092
|
-
|
|
4151
|
+
if (!newValue.startsWith('blob:')) {
|
|
4152
|
+
fileName = new URL(newValue).pathname.split('/').pop() || undefined;
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
4155
|
+
else if (source.kind === 'existing') {
|
|
4156
|
+
isExistingFileReference = true;
|
|
4157
|
+
fileName = newValue;
|
|
4093
4158
|
}
|
|
4094
4159
|
else {
|
|
4095
4160
|
fileData = newValue;
|
|
@@ -4099,18 +4164,6 @@ const saveFile = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
4099
4164
|
fileName = newValue.name;
|
|
4100
4165
|
fileData = await newValue.arrayBuffer(); // Blob API: works in browsers and Node (no FileReader in Node)
|
|
4101
4166
|
}
|
|
4102
|
-
// Handle existing file reference: filename from listFiles() that exists in files folder
|
|
4103
|
-
let isExistingFileReference = false;
|
|
4104
|
-
if (typeof newValue === 'string' &&
|
|
4105
|
-
getDataTypeFromString(newValue) === null) {
|
|
4106
|
-
const existingFilePath = BaseFileManager.getFilesPath('files', newValue);
|
|
4107
|
-
const pathExistsResult = await BaseFileManager.pathExists(existingFilePath);
|
|
4108
|
-
if (pathExistsResult) {
|
|
4109
|
-
isExistingFileReference = true;
|
|
4110
|
-
fileName = newValue;
|
|
4111
|
-
fileData = undefined;
|
|
4112
|
-
}
|
|
4113
|
-
}
|
|
4114
4167
|
if (!fileData && !isExistingFileReference) {
|
|
4115
4168
|
throw new Error('No file data found');
|
|
4116
4169
|
}
|
|
@@ -4121,6 +4174,9 @@ const saveFile = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
4121
4174
|
if (!fileName) {
|
|
4122
4175
|
fileName = newFileSeedLocalId;
|
|
4123
4176
|
}
|
|
4177
|
+
else if (!isExistingFileReference) {
|
|
4178
|
+
fileName = storageFileNameForNewSeed(newFileSeedLocalId, fileName);
|
|
4179
|
+
}
|
|
4124
4180
|
const filePath = BaseFileManager.getFilesPath('files', fileName);
|
|
4125
4181
|
await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath('files'));
|
|
4126
4182
|
await createVersion({
|
|
@@ -4331,7 +4387,7 @@ const saveRelation = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
4331
4387
|
}
|
|
4332
4388
|
const _saveRelation = async () => {
|
|
4333
4389
|
// Use dynamic import to break circular dependency
|
|
4334
|
-
const schemaMod = await import('./index-
|
|
4390
|
+
const schemaMod = await import('./index-CqnU-5i0.js');
|
|
4335
4391
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
4336
4392
|
if (!propertyNameRaw) {
|
|
4337
4393
|
throw new Error('propertyName is required');
|
|
@@ -4623,6 +4679,9 @@ const saveItemStorage = fromCallback(({ sendBack, input: { context, event } }) =
|
|
|
4623
4679
|
.set({
|
|
4624
4680
|
refResolvedValue: fileName,
|
|
4625
4681
|
localStorageDir,
|
|
4682
|
+
// The draft is as new as its content (see updateItemPropertyValue).
|
|
4683
|
+
createdAt: Date.now(),
|
|
4684
|
+
updatedAt: Date.now(),
|
|
4626
4685
|
// Same shape as a row the migration or publish converted (convertVerbatimItemStorageRow).
|
|
4627
4686
|
...(clearsVerbatimValue && { propertyValue: null, refValueType: 'file' }),
|
|
4628
4687
|
})
|
|
@@ -4669,6 +4728,30 @@ const withListRelationStorageName = (context) => {
|
|
|
4669
4728
|
return context;
|
|
4670
4729
|
return { ...context, propertyName: storageName, isRelation: true };
|
|
4671
4730
|
};
|
|
4731
|
+
/**
|
|
4732
|
+
* List values are stored as JSON array strings. Whichever actor or event delivers one, a List
|
|
4733
|
+
* property holds the array, so `value` reads the same on a new item and after a reload.
|
|
4734
|
+
*/
|
|
4735
|
+
const withListValueParsed = (context) => {
|
|
4736
|
+
if (normalizePropertyRecordSchema(context.propertyRecordSchema ?? {})?.dataType !== 'List')
|
|
4737
|
+
return context;
|
|
4738
|
+
const parse = (value) => {
|
|
4739
|
+
if (typeof value !== 'string' || !value.trimStart().startsWith('['))
|
|
4740
|
+
return value;
|
|
4741
|
+
try {
|
|
4742
|
+
const parsed = JSON.parse(value);
|
|
4743
|
+
return Array.isArray(parsed) ? parsed : value;
|
|
4744
|
+
}
|
|
4745
|
+
catch {
|
|
4746
|
+
return value;
|
|
4747
|
+
}
|
|
4748
|
+
};
|
|
4749
|
+
const propertyValue = parse(context.propertyValue);
|
|
4750
|
+
const renderValue = parse(context.renderValue);
|
|
4751
|
+
if (propertyValue === context.propertyValue && renderValue === context.renderValue)
|
|
4752
|
+
return context;
|
|
4753
|
+
return { ...context, propertyValue, renderValue };
|
|
4754
|
+
};
|
|
4672
4755
|
const propertyMachine = setup({
|
|
4673
4756
|
types: {
|
|
4674
4757
|
context: {},
|
|
@@ -4736,9 +4819,7 @@ const propertyMachine = setup({
|
|
|
4736
4819
|
}
|
|
4737
4820
|
newContext[key] = event[key];
|
|
4738
4821
|
}
|
|
4739
|
-
return 'propertyRecordSchema' in event
|
|
4740
|
-
? withListRelationStorageName(newContext)
|
|
4741
|
-
: newContext;
|
|
4822
|
+
return withListValueParsed('propertyRecordSchema' in event ? withListRelationStorageName(newContext) : newContext);
|
|
4742
4823
|
}),
|
|
4743
4824
|
},
|
|
4744
4825
|
destroyStarted: {
|
|
@@ -4790,7 +4871,7 @@ const propertyMachine = setup({
|
|
|
4790
4871
|
target: 'idle',
|
|
4791
4872
|
actions: assign(({ context, event }) => {
|
|
4792
4873
|
const property = event.property;
|
|
4793
|
-
return withListRelationStorageName({
|
|
4874
|
+
return withListValueParsed(withListRelationStorageName({
|
|
4794
4875
|
...context,
|
|
4795
4876
|
propertyName: property.propertyName || context.propertyName,
|
|
4796
4877
|
propertyValue: property.propertyValue !== undefined ? property.propertyValue : context.propertyValue,
|
|
@@ -4808,7 +4889,7 @@ const propertyMachine = setup({
|
|
|
4808
4889
|
refResolvedValue: property.refResolvedValue !== undefined ? property.refResolvedValue : context.refResolvedValue,
|
|
4809
4890
|
refResolvedDisplayValue: property.refResolvedDisplayValue !== undefined ? property.refResolvedDisplayValue : context.refResolvedDisplayValue,
|
|
4810
4891
|
localStorageDir: property.localStorageDir !== undefined ? property.localStorageDir : context.localStorageDir,
|
|
4811
|
-
});
|
|
4892
|
+
}));
|
|
4812
4893
|
}),
|
|
4813
4894
|
},
|
|
4814
4895
|
loadOrCreatePropertyError: {
|
|
@@ -5025,12 +5106,12 @@ const getPropertyData = async ({ propertyName, seedLocalId, seedUid, modelName,
|
|
|
5025
5106
|
let names = [...getMetadataPropertyNamesForQuery(propertyName)];
|
|
5026
5107
|
if (modelName) {
|
|
5027
5108
|
try {
|
|
5028
|
-
const
|
|
5029
|
-
const
|
|
5030
|
-
const { Model } =
|
|
5031
|
-
const
|
|
5032
|
-
const
|
|
5033
|
-
const { resolveItemModelFileId } =
|
|
5109
|
+
const _mod_11 = await import('./errors-Cl8rbtKR.js');
|
|
5110
|
+
const _ns_11 = _mod_11.h;
|
|
5111
|
+
const { Model } = _ns_11;
|
|
5112
|
+
const _mod_12 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
5113
|
+
const _ns_12 = _mod_12.b2;
|
|
5114
|
+
const { resolveItemModelFileId } = _ns_12;
|
|
5034
5115
|
// Model names are only unique per schema: use the seed's own model when it is recorded.
|
|
5035
5116
|
const modelFileId = await resolveItemModelFileId({ seedLocalId, seedUid });
|
|
5036
5117
|
const model = await Model.resolveAsync(modelName, { modelFileId });
|
|
@@ -5076,31 +5157,17 @@ var getPropertyData$1 = /*#__PURE__*/Object.freeze({
|
|
|
5076
5157
|
});
|
|
5077
5158
|
|
|
5078
5159
|
/**
|
|
5079
|
-
*
|
|
5160
|
+
* Release one reference to a cached entity instance. When none remain, remove it from the
|
|
5161
|
+
* caches, clean up its subscriptions and stop its service
|
|
5080
5162
|
*
|
|
5081
5163
|
* @param instance - Entity instance to unload
|
|
5082
5164
|
* @param config - Unload configuration
|
|
5083
5165
|
*/
|
|
5084
5166
|
function unloadEntity(instance, config) {
|
|
5085
|
-
// Clean up liveQuery subscriptions
|
|
5086
|
-
const instanceState = config.instanceState.get(instance);
|
|
5087
|
-
if (instanceState) {
|
|
5088
|
-
for (const key of ['liveQuerySubscription', 'schemaLiveQuerySubscription']) {
|
|
5089
|
-
const sub = instanceState[key];
|
|
5090
|
-
if (sub?.unsubscribe) {
|
|
5091
|
-
try {
|
|
5092
|
-
sub.unsubscribe();
|
|
5093
|
-
instanceState[key] = null;
|
|
5094
|
-
}
|
|
5095
|
-
catch (error) {
|
|
5096
|
-
// Ignore errors during cleanup
|
|
5097
|
-
}
|
|
5098
|
-
}
|
|
5099
|
-
}
|
|
5100
|
-
}
|
|
5101
5167
|
// Get cache keys for this instance
|
|
5102
5168
|
const cacheKeys = config.getCacheKeys(instance);
|
|
5103
5169
|
// Remove from all caches (decrement refCount, delete if 0)
|
|
5170
|
+
let stillReferenced = false;
|
|
5104
5171
|
for (const cache of config.caches) {
|
|
5105
5172
|
for (const key of cacheKeys) {
|
|
5106
5173
|
const entry = cache.get(key);
|
|
@@ -5117,6 +5184,27 @@ function unloadEntity(instance, config) {
|
|
|
5117
5184
|
}
|
|
5118
5185
|
else {
|
|
5119
5186
|
cache.set(key, entry);
|
|
5187
|
+
stillReferenced = true;
|
|
5188
|
+
}
|
|
5189
|
+
}
|
|
5190
|
+
}
|
|
5191
|
+
}
|
|
5192
|
+
// Other holders (e.g. another hook that created the same cached instance) still use it:
|
|
5193
|
+
// keep its subscriptions and service running. Stopping here broke them.
|
|
5194
|
+
if (stillReferenced)
|
|
5195
|
+
return;
|
|
5196
|
+
// Clean up liveQuery subscriptions
|
|
5197
|
+
const instanceState = config.instanceState.get(instance);
|
|
5198
|
+
if (instanceState) {
|
|
5199
|
+
for (const key of ['liveQuerySubscription', 'schemaLiveQuerySubscription']) {
|
|
5200
|
+
const sub = instanceState[key];
|
|
5201
|
+
if (sub?.unsubscribe) {
|
|
5202
|
+
try {
|
|
5203
|
+
sub.unsubscribe();
|
|
5204
|
+
instanceState[key] = null;
|
|
5205
|
+
}
|
|
5206
|
+
catch (error) {
|
|
5207
|
+
// Ignore errors during cleanup
|
|
5120
5208
|
}
|
|
5121
5209
|
}
|
|
5122
5210
|
}
|
|
@@ -5222,9 +5310,9 @@ const HTML_PROP_SEED_UID_RE = /^0x[a-fA-F0-9]{64}$/;
|
|
|
5222
5310
|
*/
|
|
5223
5311
|
const resolvePropertyRecordSchemaFromSchemaData = async (modelName, propertyName, modelType, schemaName) => {
|
|
5224
5312
|
try {
|
|
5225
|
-
const
|
|
5226
|
-
const
|
|
5227
|
-
const { loadAllSchemasFromDb } =
|
|
5313
|
+
const _mod_13 = await import('./ClientManager-De-vKHGe.js');
|
|
5314
|
+
const _ns_13 = _mod_13.K;
|
|
5315
|
+
const { loadAllSchemasFromDb } = _ns_13;
|
|
5228
5316
|
const allSchemas = await loadAllSchemasFromDb();
|
|
5229
5317
|
const modelNameAlt = modelType ? upperFirst(camelCase(modelType)) : '';
|
|
5230
5318
|
for (const { schema } of allSchemas) {
|
|
@@ -5276,13 +5364,13 @@ hints = {}) => {
|
|
|
5276
5364
|
return undefined;
|
|
5277
5365
|
}
|
|
5278
5366
|
try {
|
|
5279
|
-
const
|
|
5280
|
-
const
|
|
5281
|
-
const { Model } =
|
|
5282
|
-
const { modelPropertiesToObject } = await import('./model-
|
|
5283
|
-
const
|
|
5284
|
-
const
|
|
5285
|
-
const { resolveItemModelFileId } =
|
|
5367
|
+
const _mod_14 = await import('./errors-Cl8rbtKR.js');
|
|
5368
|
+
const _ns_14 = _mod_14.h;
|
|
5369
|
+
const { Model } = _ns_14;
|
|
5370
|
+
const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
|
|
5371
|
+
const _mod_15 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
5372
|
+
const _ns_15 = _mod_15.b2;
|
|
5373
|
+
const { resolveItemModelFileId } = _ns_15;
|
|
5286
5374
|
const modelFileId = await resolveItemModelFileId(hints);
|
|
5287
5375
|
let model = modelFileId
|
|
5288
5376
|
? await Model.resolveAsync(modelName || modelTypeToModelName(modelType ?? ''), { modelFileId })
|
|
@@ -5440,7 +5528,7 @@ class ItemProperty {
|
|
|
5440
5528
|
return;
|
|
5441
5529
|
}
|
|
5442
5530
|
// Use dynamic import to break circular dependency
|
|
5443
|
-
const schemaMod = await import('./index-
|
|
5531
|
+
const schemaMod = await import('./index-CqnU-5i0.js');
|
|
5444
5532
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
5445
5533
|
const { context } = snapshot;
|
|
5446
5534
|
const { propertyRecordSchema } = context;
|
|
@@ -5611,9 +5699,9 @@ class ItemProperty {
|
|
|
5611
5699
|
const normalizedRefValueType = normalizeDataType(propertyRecordSchema?.refValueType);
|
|
5612
5700
|
const propertyNames = getMetadataPropertyNamesForQuery(propertyName, normalizedDataType, normalizedRefValueType);
|
|
5613
5701
|
const propertyNameVariant = propertyNames.length > 1 ? propertyNames[1] : undefined;
|
|
5614
|
-
const
|
|
5615
|
-
const
|
|
5616
|
-
const seedSchemaMod =
|
|
5702
|
+
const _mod_16 = await import('./index-DAl9U4rn.js');
|
|
5703
|
+
const _ns_16 = _mod_16.s;
|
|
5704
|
+
const seedSchemaMod = _ns_16;
|
|
5617
5705
|
const { metadata } = seedSchemaMod;
|
|
5618
5706
|
const drizzleMod = await import('drizzle-orm');
|
|
5619
5707
|
const { eq, and, or } = drizzleMod;
|
|
@@ -5745,6 +5833,14 @@ class ItemProperty {
|
|
|
5745
5833
|
return;
|
|
5746
5834
|
const metaRow = metadataRows[0];
|
|
5747
5835
|
logger(`[ItemProperty._setupLiveQuerySubscription] Metadata updated in database for propertyName: ${propertyName}`);
|
|
5836
|
+
// While this property has a save pending, the row is older than the value in memory
|
|
5837
|
+
// (the user may still be typing): showing it would drop keystrokes, and another tab's
|
|
5838
|
+
// write would replace the value being typed. The save sets the context itself.
|
|
5839
|
+
const { context } = this._service.getSnapshot();
|
|
5840
|
+
if (context.isSaving ||
|
|
5841
|
+
hasPendingPropertyWrite(propertyWriteKey(context.seedLocalId ?? context.seedUid, context.propertyName))) {
|
|
5842
|
+
return;
|
|
5843
|
+
}
|
|
5748
5844
|
// Update context with metadata changes
|
|
5749
5845
|
this._service.send({
|
|
5750
5846
|
type: 'updateContext',
|
|
@@ -5827,9 +5923,9 @@ class ItemProperty {
|
|
|
5827
5923
|
const ctx = this._service.getSnapshot().context;
|
|
5828
5924
|
let modelFileId;
|
|
5829
5925
|
try {
|
|
5830
|
-
const
|
|
5831
|
-
const
|
|
5832
|
-
const { resolveItemModelFileId } =
|
|
5926
|
+
const _mod_17 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
5927
|
+
const _ns_17 = _mod_17.b2;
|
|
5928
|
+
const { resolveItemModelFileId } = _ns_17;
|
|
5833
5929
|
modelFileId = await resolveItemModelFileId({
|
|
5834
5930
|
modelFileId: ctx.modelFileId,
|
|
5835
5931
|
seedLocalId: ctx.seedLocalId,
|
|
@@ -6190,9 +6286,9 @@ class ItemProperty {
|
|
|
6190
6286
|
const propertiesData = await getItemProperties({ seedLocalId, seedUid });
|
|
6191
6287
|
const instances = [];
|
|
6192
6288
|
const seenNormalized = new Set();
|
|
6193
|
-
const
|
|
6194
|
-
const
|
|
6195
|
-
const { resolveItemModelFileId } =
|
|
6289
|
+
const _mod_18 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
6290
|
+
const _ns_18 = _mod_18.b2;
|
|
6291
|
+
const { resolveItemModelFileId } = _ns_18;
|
|
6196
6292
|
const itemModelFileId = await resolveItemModelFileId({ seedLocalId, seedUid });
|
|
6197
6293
|
for (const data of propertiesData) {
|
|
6198
6294
|
const d = data;
|
|
@@ -6208,10 +6304,10 @@ class ItemProperty {
|
|
|
6208
6304
|
}
|
|
6209
6305
|
else if (baseName) {
|
|
6210
6306
|
try {
|
|
6211
|
-
const
|
|
6212
|
-
const
|
|
6213
|
-
const { Model } =
|
|
6214
|
-
const { modelPropertiesToObject } = await import('./model-
|
|
6307
|
+
const _mod_19 = await import('./errors-Cl8rbtKR.js');
|
|
6308
|
+
const _ns_19 = _mod_19.h;
|
|
6309
|
+
const { Model } = _ns_19;
|
|
6310
|
+
const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
|
|
6215
6311
|
const model = await Model.resolveAsync(modelName, { modelFileId });
|
|
6216
6312
|
if (model?.properties) {
|
|
6217
6313
|
const schemas = modelPropertiesToObject(model.properties);
|
|
@@ -6225,10 +6321,10 @@ class ItemProperty {
|
|
|
6225
6321
|
}
|
|
6226
6322
|
if (modelName && propertyName) {
|
|
6227
6323
|
try {
|
|
6228
|
-
const
|
|
6229
|
-
const
|
|
6230
|
-
const { Model } =
|
|
6231
|
-
const { modelPropertiesToObject } = await import('./model-
|
|
6324
|
+
const _mod_20 = await import('./errors-Cl8rbtKR.js');
|
|
6325
|
+
const _ns_20 = _mod_20.h;
|
|
6326
|
+
const { Model } = _ns_20;
|
|
6327
|
+
const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
|
|
6232
6328
|
const model = await Model.resolveAsync(modelName, { modelFileId });
|
|
6233
6329
|
if (model?.properties?.length) {
|
|
6234
6330
|
const schemas = modelPropertiesToObject(model.properties);
|
|
@@ -6557,9 +6653,9 @@ class ItemProperty {
|
|
|
6557
6653
|
if (!propertyName || (!seedLocalId && !seedUid))
|
|
6558
6654
|
return;
|
|
6559
6655
|
if (db) {
|
|
6560
|
-
const
|
|
6561
|
-
const
|
|
6562
|
-
const seedSchemaMod =
|
|
6656
|
+
const _mod_21 = await import('./index-DAl9U4rn.js');
|
|
6657
|
+
const _ns_21 = _mod_21.s;
|
|
6658
|
+
const seedSchemaMod = _ns_21;
|
|
6563
6659
|
const { metadata } = seedSchemaMod;
|
|
6564
6660
|
const drizzleMod = await import('drizzle-orm');
|
|
6565
6661
|
const { and, eq } = drizzleMod;
|
|
@@ -6602,9 +6698,9 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
|
|
|
6602
6698
|
}
|
|
6603
6699
|
const seedType = toSnakeCase(modelName);
|
|
6604
6700
|
// Dynamic import to break circular dependency
|
|
6605
|
-
const
|
|
6606
|
-
const
|
|
6607
|
-
const modelMod =
|
|
6701
|
+
const _mod_22 = await import('./errors-Cl8rbtKR.js');
|
|
6702
|
+
const _ns_22 = _mod_22.h;
|
|
6703
|
+
const modelMod = _ns_22;
|
|
6608
6704
|
const { Model } = modelMod;
|
|
6609
6705
|
const model = await Model.resolveAsync(modelName, { modelFileId });
|
|
6610
6706
|
const propertySchemas = model?.properties ? modelPropertiesToObject(model.properties) : undefined;
|
|
@@ -6785,9 +6881,9 @@ const getModel = () => {
|
|
|
6785
6881
|
// the fragile `import(...).then(n => n.X)` chunk-namespace pattern.
|
|
6786
6882
|
if (!modelImportPromise) {
|
|
6787
6883
|
modelImportPromise = (async () => {
|
|
6788
|
-
const
|
|
6789
|
-
const
|
|
6790
|
-
const mod =
|
|
6884
|
+
const _mod_23 = await import('./errors-Cl8rbtKR.js');
|
|
6885
|
+
const _ns_23 = _mod_23.h;
|
|
6886
|
+
const mod = _ns_23;
|
|
6791
6887
|
ModelClass = mod.Model;
|
|
6792
6888
|
return mod;
|
|
6793
6889
|
})();
|
|
@@ -6953,14 +7049,14 @@ class Item {
|
|
|
6953
7049
|
};
|
|
6954
7050
|
this.getPublishUploads = async (options) => {
|
|
6955
7051
|
// Use dynamic import to break circular dependency
|
|
6956
|
-
const getPublishUploadsMod = await import('./getPublishUploads-
|
|
7052
|
+
const getPublishUploadsMod = await import('./getPublishUploads-DJ1UPh7i.js');
|
|
6957
7053
|
const { getPublishUploads } = getPublishUploadsMod;
|
|
6958
7054
|
return await getPublishUploads(this, [], undefined, options);
|
|
6959
7055
|
};
|
|
6960
7056
|
this.getPublishPayload = async (uploadedTransactions, options) => {
|
|
6961
|
-
const
|
|
6962
|
-
const
|
|
6963
|
-
const getPublishPayloadMod =
|
|
7057
|
+
const _mod_24 = await import('./getPublishPayload-C278kK9P.js');
|
|
7058
|
+
const _ns_24 = _mod_24.g;
|
|
7059
|
+
const getPublishPayloadMod = _ns_24;
|
|
6964
7060
|
const { getPublishPayload } = getPublishPayloadMod;
|
|
6965
7061
|
return await getPublishPayload(this, uploadedTransactions, options);
|
|
6966
7062
|
};
|
|
@@ -7494,26 +7590,32 @@ class Item {
|
|
|
7494
7590
|
const db = BaseDb.getAppDb();
|
|
7495
7591
|
if (db && props.modelName) {
|
|
7496
7592
|
// Model names are only unique per schema: resolve the exact models row from the most specific scope.
|
|
7497
|
-
const
|
|
7498
|
-
const
|
|
7499
|
-
const { resolveModelRecord } =
|
|
7593
|
+
const _mod_25 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
7594
|
+
const _ns_25 = _mod_25.b2;
|
|
7595
|
+
const { resolveModelRecord } = _ns_25;
|
|
7500
7596
|
const modelRecord = await resolveModelRecord(props.modelName, {
|
|
7501
7597
|
modelFileId: props.modelFileId ?? modelInstance?.id,
|
|
7502
7598
|
schemaName: schemaName ?? modelInstance?.schemaName,
|
|
7503
7599
|
});
|
|
7504
7600
|
const modelRecords = modelRecord ? [modelRecord] : [];
|
|
7601
|
+
if (!modelRecord) {
|
|
7602
|
+
const _mod_26 = await import('./errors-Cl8rbtKR.js');
|
|
7603
|
+
const _ns_26 = _mod_26.j;
|
|
7604
|
+
const { UnknownModelError } = _ns_26;
|
|
7605
|
+
throw new UnknownModelError(props.modelName, schemaName ?? modelInstance?.schemaName);
|
|
7606
|
+
}
|
|
7505
7607
|
if (modelRecord?.schemaFileId) {
|
|
7506
7608
|
props.modelFileId = modelRecord.schemaFileId;
|
|
7507
7609
|
}
|
|
7508
7610
|
// Scope the constructor's Model lookup to this model's schema (as getItemData does on reload),
|
|
7509
7611
|
// so a same-named model cached from another schema can't supply the property set.
|
|
7510
7612
|
if (modelRecord && !props.schemaName) {
|
|
7511
|
-
const
|
|
7613
|
+
const _mod_27 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
7614
|
+
const _ns_27 = _mod_27.b1;
|
|
7615
|
+
const { modelSchemas } = _ns_27;
|
|
7616
|
+
const _mod_28 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
7512
7617
|
const _ns_28 = _mod_28.b0;
|
|
7513
|
-
const {
|
|
7514
|
-
const _mod_29 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
7515
|
-
const _ns_29 = _mod_29.a$;
|
|
7516
|
-
const { schemas: schemasTable } = _ns_29;
|
|
7618
|
+
const { schemas: schemasTable } = _ns_28;
|
|
7517
7619
|
const schemaRows = await db
|
|
7518
7620
|
.select({ schemaName: schemasTable.name })
|
|
7519
7621
|
.from(modelSchemas)
|
|
@@ -7567,6 +7669,12 @@ class Item {
|
|
|
7567
7669
|
modelPropertyData[key] = value;
|
|
7568
7670
|
}
|
|
7569
7671
|
}
|
|
7672
|
+
// Strict by default: unknown keys and invalid values reject before anything is written.
|
|
7673
|
+
// Values that go through the property save pipeline (files, Html, ItemStorage) are
|
|
7674
|
+
// validated there.
|
|
7675
|
+
if (propertyNames.length > 0 && options?.validate !== false) {
|
|
7676
|
+
await Item.assertValidCreateValues(props, propertyNames, dataTypeByPropertyName, new Set(pipelineValues.map(([key]) => key)));
|
|
7677
|
+
}
|
|
7570
7678
|
const { seedLocalId, versionLocalId, } = await createNewItem(modelPropertyData);
|
|
7571
7679
|
props.seedLocalId = seedLocalId;
|
|
7572
7680
|
props.latestVersionLocalId = versionLocalId;
|
|
@@ -7864,9 +7972,9 @@ class Item {
|
|
|
7864
7972
|
if (!appDb || Item.instanceCache.size === 0) {
|
|
7865
7973
|
return;
|
|
7866
7974
|
}
|
|
7867
|
-
const
|
|
7868
|
-
const
|
|
7869
|
-
const { metadata } =
|
|
7975
|
+
const _mod_29 = await import('./index-DAl9U4rn.js');
|
|
7976
|
+
const _ns_29 = _mod_29.s;
|
|
7977
|
+
const { metadata } = _ns_29;
|
|
7870
7978
|
const { eq, and } = await import('drizzle-orm');
|
|
7871
7979
|
const dedupedInstances = new Map();
|
|
7872
7980
|
for (const entry of Item.instanceCache.values()) {
|
|
@@ -8025,7 +8133,64 @@ class Item {
|
|
|
8025
8133
|
});
|
|
8026
8134
|
state.definedPropertyNames.add(propertyName);
|
|
8027
8135
|
}
|
|
8028
|
-
/**
|
|
8136
|
+
/** Throws ItemCreateValidationError for unknown keys and values that break their property's rules. */
|
|
8137
|
+
static async assertValidCreateValues(props, propertyNames, dataTypeByPropertyName, skipKeys) {
|
|
8138
|
+
const _mod_30 = await import('./errors-Cl8rbtKR.js');
|
|
8139
|
+
const _ns_30 = _mod_30.j;
|
|
8140
|
+
const { ItemCreateValidationError } = _ns_30;
|
|
8141
|
+
const { getPropertySchema } = await import('./property-Brgr5RdT.js');
|
|
8142
|
+
const { SchemaValidationService } = await import('./SchemaValidationService-DViJ056F.js');
|
|
8143
|
+
const validationService = new SchemaValidationService();
|
|
8144
|
+
const modelName = props.modelName;
|
|
8145
|
+
const known = new Set(propertyNames);
|
|
8146
|
+
const problems = [];
|
|
8147
|
+
for (const [key, value] of Object.entries(props)) {
|
|
8148
|
+
if (Item.CREATE_METADATA_KEYS.has(key) || skipKeys.has(key))
|
|
8149
|
+
continue;
|
|
8150
|
+
if (!known.has(key)) {
|
|
8151
|
+
problems.push({
|
|
8152
|
+
property: key,
|
|
8153
|
+
code: 'unknown_property',
|
|
8154
|
+
message: `${modelName} has no property "${key}"`,
|
|
8155
|
+
});
|
|
8156
|
+
continue;
|
|
8157
|
+
}
|
|
8158
|
+
if (value === undefined || value === null)
|
|
8159
|
+
continue;
|
|
8160
|
+
const propertySchema = await getPropertySchema(modelName, key, {
|
|
8161
|
+
modelFileId: props.modelFileId,
|
|
8162
|
+
schemaName: props.schemaName,
|
|
8163
|
+
});
|
|
8164
|
+
const dataType = normalizeDataType(propertySchema?.dataType ?? dataTypeByPropertyName.get(key) ?? '');
|
|
8165
|
+
if (!dataType)
|
|
8166
|
+
continue;
|
|
8167
|
+
// Lists may be passed as the JSON array string they are stored as.
|
|
8168
|
+
let checked = value;
|
|
8169
|
+
if (dataType === ModelPropertyDataTypes.List && typeof value === 'string') {
|
|
8170
|
+
try {
|
|
8171
|
+
const parsed = JSON.parse(value);
|
|
8172
|
+
if (Array.isArray(parsed))
|
|
8173
|
+
checked = parsed;
|
|
8174
|
+
}
|
|
8175
|
+
catch {
|
|
8176
|
+
// Not JSON: validated as given, and rejected as a non-array
|
|
8177
|
+
}
|
|
8178
|
+
}
|
|
8179
|
+
const { resolvePropertyValidationRules } = await import('./propertyValidationRules-CDRitiiK.js');
|
|
8180
|
+
const rules = propertySchema?.validation ??
|
|
8181
|
+
(await resolvePropertyValidationRules(modelName, key, {
|
|
8182
|
+
modelFileId: props.modelFileId,
|
|
8183
|
+
schemaName: props.schemaName,
|
|
8184
|
+
}));
|
|
8185
|
+
const result = validationService.validatePropertyValue(checked, dataType, rules, propertySchema?.refValueType);
|
|
8186
|
+
for (const error of result.errors) {
|
|
8187
|
+
problems.push({ property: key, code: error.code, message: error.message });
|
|
8188
|
+
}
|
|
8189
|
+
}
|
|
8190
|
+
if (problems.length > 0) {
|
|
8191
|
+
throw new ItemCreateValidationError(modelName, problems);
|
|
8192
|
+
}
|
|
8193
|
+
}
|
|
8029
8194
|
/**
|
|
8030
8195
|
* Set `publisher` on loaded Items for these seeds (after claimUnpublishedDrafts stamped
|
|
8031
8196
|
* their rows). Items that aren't loaded read it from the DB when they load.
|
|
@@ -8342,7 +8507,7 @@ class Item {
|
|
|
8342
8507
|
itemActor.send(event);
|
|
8343
8508
|
};
|
|
8344
8509
|
try {
|
|
8345
|
-
const _mod_31 = await import('./index-
|
|
8510
|
+
const _mod_31 = await import('./index-DAl9U4rn.js');
|
|
8346
8511
|
const _ns_31 = _mod_31.s;
|
|
8347
8512
|
const seedSchemaMod = _ns_31;
|
|
8348
8513
|
const { seeds, versions, metadata } = seedSchemaMod;
|
|
@@ -8691,6 +8856,15 @@ class Item {
|
|
|
8691
8856
|
}
|
|
8692
8857
|
}
|
|
8693
8858
|
Item.instanceCache = new Map();
|
|
8859
|
+
/** Same as `item.publish(options)`; requires @seedprotocol/publish. */
|
|
8860
|
+
/** Keys Item.create accepts besides the model's properties. */
|
|
8861
|
+
Item.CREATE_METADATA_KEYS = new Set([
|
|
8862
|
+
'modelName', 'schemaName', 'modelInstance', 'modelFileId', 'type',
|
|
8863
|
+
'seedLocalId', 'seedUid', 'schemaUid', 'attestationCreatedAt',
|
|
8864
|
+
'latestVersionUid', 'latestVersionLocalId', 'publishedVersionUid', 'publishedVersionLocalId',
|
|
8865
|
+
'versionsCount', 'lastVersionPublishedAt', 'lastLocalUpdateAt',
|
|
8866
|
+
'createdAt', 'updatedAt', 'publisher', 'revokedAt',
|
|
8867
|
+
]);
|
|
8694
8868
|
|
|
8695
8869
|
var Item$1 = /*#__PURE__*/Object.freeze({
|
|
8696
8870
|
__proto__: null,
|
|
@@ -8698,4 +8872,4 @@ var Item$1 = /*#__PURE__*/Object.freeze({
|
|
|
8698
8872
|
});
|
|
8699
8873
|
|
|
8700
8874
|
export { getInvariantSafePropertyDescriptor as $, getGetPublisherForNewSeeds as A, getMetadataLatest as B, ClientManagerState as C, DEFAULT_READY_TIMEOUT_MS as D, getPublishExecutor as E, getRevokeExecutor as F, getUploadExecutor as G, getVersionData$1 as H, Item as I, isLocalUnsealedDraft as J, isSeedRowOwned as K, localUnsealedDraftSql as L, METADATA_LATEST_FIRST_ORDER_SQL as M, ownedPublisherSql as N, OwnershipError as O, PUBLISH_NOT_CONFIGURED_MESSAGE as P, ownedSeedsSql as Q, pickLatestMetadataRowPerProperty as R, placeholderUidSql as S, propertyMachine as T, publisherInAddressListSql as U, publisherIsInOwnedSet as V, setAdditionalSyncAddresses as W, setGetPublisherForNewSeeds as X, setPublishExecutor as Y, setRevokeExecutor as Z, setUploadExecutor as _, chunkValues as a, clearDestroySubscriptions as a0, unloadEntity as a1, ClientManagerEvents as a2, withLockedItemStorageRow as a3, getItemStorageFilePath as a4, writeItemStorageFile as a5, resolvePublisherFromSeedRow as a6, getPropertyData$1 as a7, Item$1 as a8, rowsPerInsert as b, compareMetadataRowsLatestFirst as c, getGetAdditionalSyncAddresses as d, ItemProperty as e, ItemPropertySaveValidationError as f, getItemData as g, assertItemOwned as h, isItemOwned as i, getEasSchemaUidForModel as j, getLatestPublishedVersionRow as k, listRelationEasPropertyName as l, isVersionRevoked as m, waitForEntityIdle as n, createReactiveProxy as o, parseListPropertyValueFromStorage as p, findEntity as q, resolveStorageNameToSchemaName as r, selectInBatches as s, forceRemoveFromCaches as t, runDestroyLifecycle as u, isPublishedMetadataRow as v, writeInBatches as w, MachineIds as x, createNewItem as y, getEasSchemaForItemProperty as z };
|
|
8701
|
-
//# sourceMappingURL=Item-
|
|
8875
|
+
//# sourceMappingURL=Item-cq9VcsAY.js.map
|