Skip to content

Commit

Permalink
feat: support for linked wearable mappings (#278)
Browse files Browse the repository at this point in the history
  • Loading branch information
marianogoldman authored Jul 10, 2024
1 parent e1e2269 commit 30e09f4
Show file tree
Hide file tree
Showing 10 changed files with 510 additions and 10 deletions.
85 changes: 84 additions & 1 deletion report/schemas.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ export enum AnalyticsDayDataSortBy {
MOST_SALES = "most_sales"
}

// @alpha
export type AnyMapping = {
type: MappingType.ANY;
};

// @alpha
export namespace AnyMapping {
const // (undocumented)
schema: JSONSchema<AnyMapping>;
const // (undocumented)
validate: ValidateFunction<Mapping>;
}

// @public
export type AuthChain = AuthLink[];

Expand Down Expand Up @@ -1180,6 +1193,29 @@ export namespace Locale {
validate: ValidateFunction<Locale>;
}

// @alpha
export type Mapping = SingleMapping | AnyMapping | RangeMapping | MultipleMapping;

// @alpha
export namespace Mapping {
const // (undocumented)
schema: JSONSchema<Mapping>;
const // (undocumented)
validate: ValidateFunction<Mapping>;
}

// @alpha
export enum MappingType {
// (undocumented)
ANY = "any",
// (undocumented)
MULTIPLE = "multiple",
// (undocumented)
RANGE = "range",
// (undocumented)
SINGLE = "single"
}

// @alpha
export type MerkleProof = {
proof: string[];
Expand Down Expand Up @@ -1286,6 +1322,20 @@ export enum MintSortBy {
RECENTLY_MINTED = "recently_minted"
}

// @alpha
export type MultipleMapping = {
type: MappingType.MULTIPLE;
ids: string[];
};

// @alpha
export namespace MultipleMapping {
const // (undocumented)
schema: JSONSchema<MultipleMapping>;
const // (undocumented)
validate: ValidateFunction<Mapping>;
}

// @alpha
export enum Network {
// (undocumented)
Expand Down Expand Up @@ -2004,6 +2054,23 @@ export namespace ProviderType {
validate: ValidateFunction<ProviderType>;
}

// @alpha
export type RangeMapping = {
type: MappingType.RANGE;
from: string;
to: string;
};

// @alpha
export namespace RangeMapping {
const // (undocumented)
_fromLessThanOrEqualTo: KeywordDefinition;
const // (undocumented)
schema: JSONSchema<RangeMapping>;
const // (undocumented)
validate: ValidateFunction<Mapping>;
}

// Warning: (ae-missing-release-tag) "Rarity" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
// Warning: (ae-missing-release-tag) "Rarity" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
Expand Down Expand Up @@ -2410,6 +2477,20 @@ export const sendMessage: <T extends PreviewMessageType>(window: {
postMessage(event: any, targetOrigin: string): any;
}, type: T, payload: PreviewMessagePayload<T>, targetOrigin?: string) => void;

// @alpha
export type SingleMapping = {
type: MappingType.SINGLE;
id: string;
};

// @alpha
export namespace SingleMapping {
const // (undocumented)
schema: JSONSchema<SingleMapping>;
const // (undocumented)
validate: ValidateFunction<Mapping>;
}

// @alpha
export type Snapshots = {
face256: IPFSv2;
Expand Down Expand Up @@ -2560,6 +2641,7 @@ export type SyncDeployment = SnapshotSyncDeployment | PointerChangesSyncDeployme
export type ThirdPartyProps = {
merkleProof: MerkleProof;
content: Record<string, string>;
mappings?: Mapping[];
};

// Warning: (ae-missing-release-tag) "Trade" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
Expand Down Expand Up @@ -2937,7 +3019,8 @@ export namespace WorldConfiguration {
// src/platform/events/blockchain.ts:19:3 - (ae-forgotten-export) The symbol "BidMetadata" needs to be exported by the entry point index.d.ts
// src/platform/events/blockchain.ts:60:3 - (ae-forgotten-export) The symbol "RentalMetadata" needs to be exported by the entry point index.d.ts
// src/platform/item/emote/adr74/emote-data-adr74.ts:7:3 - (ae-incompatible-release-tags) The symbol "representations" is marked as @public, but its signature references "EmoteRepresentationADR74" which is marked as @alpha
// src/platform/item/third-party-props.ts:6:3 - (ae-incompatible-release-tags) The symbol "merkleProof" is marked as @public, but its signature references "MerkleProof" which is marked as @alpha
// src/platform/item/third-party-props.ts:7:3 - (ae-incompatible-release-tags) The symbol "merkleProof" is marked as @public, but its signature references "MerkleProof" which is marked as @alpha
// src/platform/item/third-party-props.ts:9:3 - (ae-incompatible-release-tags) The symbol "mappings" is marked as @public, but its signature references "Mapping" which is marked as @alpha
// src/platform/scene/feature-toggles.ts:11:3 - (ae-forgotten-export) The symbol "EnabledDisabled" needs to be exported by the entry point index.d.ts
// src/platform/scene/feature-toggles.ts:12:3 - (ae-forgotten-export) The symbol "PortableExperiencesToggles" needs to be exported by the entry point index.d.ts
// src/platform/scene/spawn-point.ts:6:3 - (ae-forgotten-export) The symbol "SinglePosition" needs to be exported by the entry point index.d.ts
Expand Down
8 changes: 6 additions & 2 deletions src/platform/item/emote/emote.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isThirdParty } from '..'
import { isThirdParty, RangeMapping } from '..'
import { generateLazyValidator, JSONSchema } from '../../../validation'
import { BaseItem, baseItemProperties, isBaseEmote, requiredBaseItemProps } from '../base-item'
import { standardProperties, StandardProps } from '../standard-props'
Expand Down Expand Up @@ -77,5 +77,9 @@ export namespace Emote {
errors: false
}

export const validate = generateLazyValidator(schema, [_isThirdPartyKeywordDef, _isBaseEmoteKeywordDef])
export const validate = generateLazyValidator(schema, [
_isThirdPartyKeywordDef,
_isBaseEmoteKeywordDef,
RangeMapping._fromLessThanOrEqualTo
])
}
1 change: 1 addition & 0 deletions src/platform/item/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export { Metrics } from './metrics'
export { BodyShape } from './body-shape'
export { StandardProps, isStandard } from './standard-props'
export { ThirdPartyProps, isThirdParty } from './third-party-props'
export * from './linked-wearable-props'
export * from './wearable'
export * from './emote'
175 changes: 175 additions & 0 deletions src/platform/item/linked-wearable-props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { generateLazyValidator, JSONSchema, ValidateFunction } from '../../validation'
import { KeywordDefinition } from 'ajv'

/**
* MappingType
* @alpha
*/
export enum MappingType {
SINGLE = 'single',
ANY = 'any',
MULTIPLE = 'multiple',
RANGE = 'range'
}

/**
* Mapping
* @alpha
*/
export type Mapping = SingleMapping | AnyMapping | RangeMapping | MultipleMapping

/**
* SingleMapping
* @alpha
*/
export type SingleMapping = {
type: MappingType.SINGLE
id: string
}

/**
* AnyMapping
* @alpha
*/
export type AnyMapping = {
type: MappingType.ANY
}

/**
* RangeMapping
* @alpha
*/
export type RangeMapping = {
type: MappingType.RANGE
from: string
to: string
}

/**
* MultipleMapping
* @alpha
*/
export type MultipleMapping = {
type: MappingType.MULTIPLE
ids: string[]
}

/**
* SingleMapping
* @alpha
*/
export namespace SingleMapping {
export const schema: JSONSchema<SingleMapping> = {
type: 'object',
properties: {
type: { type: 'string', const: MappingType.SINGLE },
id: { type: 'string', pattern: '^[0-9]+$' }
},
required: ['type', 'id'],
additionalProperties: false
}

export const validate: ValidateFunction<Mapping> = generateLazyValidator(schema)
}

/**
* AnyMapping
* @alpha
*/
export namespace AnyMapping {
export const schema: JSONSchema<AnyMapping> = {
type: 'object',
properties: {
type: { type: 'string', const: MappingType.ANY }
},
required: ['type'],
additionalProperties: false
}

export const validate: ValidateFunction<Mapping> = generateLazyValidator(schema)
}

/**
* RangeMapping
* @alpha
*/
export namespace RangeMapping {
export const _fromLessThanOrEqualTo: KeywordDefinition = {
keyword: '_fromLessThanOrEqualTo',
validate: function validate(schema: boolean, data: any) {
if (!data || !data.from || !data.to) {
return false
}

let { to, from } = data
if (typeof from !== 'bigint' || typeof to !== 'bigint') {
from = BigInt(from)
to = BigInt(to)
}

return from <= to
},
errors: false
}

export const schema: JSONSchema<RangeMapping> = {
type: 'object',
properties: {
type: { type: 'string', const: MappingType.RANGE },
from: { type: 'string', pattern: '^[0-9]+$' },
to: { type: 'string', pattern: '^[0-9]+$' }
},
required: ['type', 'from', 'to'],
additionalProperties: false,
_fromLessThanOrEqualTo: true
}

export const validate: ValidateFunction<Mapping> = generateLazyValidator(schema, [_fromLessThanOrEqualTo])
}

/**
* MultipleMapping
* @alpha
*/
export namespace MultipleMapping {
export const schema: JSONSchema<MultipleMapping> = {
type: 'object',
properties: {
type: { type: 'string', const: MappingType.MULTIPLE },
ids: {
type: 'array',
items: {
type: 'string',
pattern: '^[0-9]+$'
},
minItems: 1,
uniqueItems: true
}
},
required: ['type', 'ids'],
additionalProperties: false
}
export const validate: ValidateFunction<Mapping> = generateLazyValidator(schema)
}

/**
* Mappings
* @alpha
*/
export namespace Mapping {
export const schema: JSONSchema<Mapping> = {
type: 'object',
properties: {
type: {
type: 'string',
enum: Object.values(MappingType)
}
},
required: ['type'],
oneOf: [SingleMapping.schema, AnyMapping.schema, RangeMapping.schema, MultipleMapping.schema]
}

export const validate: ValidateFunction<Mapping> = generateLazyValidator(schema, [
RangeMapping._fromLessThanOrEqualTo
])
}
16 changes: 14 additions & 2 deletions src/platform/item/third-party-props.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { generateLazyValidator, JSONSchema, ValidateFunction } from '../../validation'
import { MerkleProof } from '../merkle-tree/merkle-proof'
import { MerkleProof } from '../merkle-tree'
import { BaseItem } from './base-item'
import { Mapping, RangeMapping } from './linked-wearable-props'

export type ThirdPartyProps = {
merkleProof: MerkleProof
content: Record<string, string>
mappings?: Mapping[]
}

export const thirdPartyProps = {
Expand All @@ -14,6 +16,13 @@ export const thirdPartyProps = {
nullable: false,
additionalProperties: { type: 'string' },
required: [] as any[]
},
mappings: {
type: 'array',
items: Mapping.schema,
minItems: 1,
maxItems: 1,
nullable: true
}
} as const

Expand All @@ -38,7 +47,10 @@ const _containsHashingKeys = {
errors: false
}

const validate: ValidateFunction<ThirdPartyProps> = generateLazyValidator(schema, [_containsHashingKeys])
const validate: ValidateFunction<ThirdPartyProps> = generateLazyValidator(schema, [
_containsHashingKeys,
RangeMapping._fromLessThanOrEqualTo
])

export function isThirdParty<T extends BaseItem>(item: T): item is T & ThirdPartyProps {
return validate(item)
Expand Down
7 changes: 6 additions & 1 deletion src/platform/item/wearable/wearable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { BaseItem, baseItemProperties, isBaseAvatar, requiredBaseItemProps } fro
import { StandardProps, standardProperties } from '../standard-props'
import { isThirdParty, ThirdPartyProps, thirdPartyProps } from '../third-party-props'
import { HideableWearableCategory } from './hideable-category'
import { RangeMapping } from '../linked-wearable-props'

/** @alpha */
export type Wearable = BaseItem & {
Expand Down Expand Up @@ -115,5 +116,9 @@ export namespace Wearable {
* - merkleProof
* - content
*/
export const validate = generateLazyValidator(schema, [_isThirdPartyKeywordDef, _isBaseAvatarKeywordDef])
export const validate = generateLazyValidator(schema, [
_isThirdPartyKeywordDef,
_isBaseAvatarKeywordDef,
RangeMapping._fromLessThanOrEqualTo
])
}
Loading

0 comments on commit 30e09f4

Please sign in to comment.