@mapletip/data 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +204 -2
- package/client/contract-compatibility.mjs +10 -0
- package/client/core.d.ts +5 -0
- package/client/core.js +10 -0
- package/client/items.d.ts +28 -5
- package/client/items.js +60 -8
- package/client/map-geography.d.ts +4 -0
- package/client/map-geography.js +2 -0
- package/client/maps.d.ts +22 -0
- package/client/maps.js +25 -0
- package/client/monster-client.d.ts +14 -1
- package/client/monster-client.js +55 -3
- package/client/monsters.d.ts +37 -8
- package/client/monsters.js +51 -0
- package/client/static-client.d.ts +7 -5
- package/client/static-client.js +3 -2
- package/client/static-domains.d.ts +8 -1
- package/client/static-domains.js +27 -3
- package/generated/item-browse-pack-2.d.ts +83 -1
- package/generated/item-browse-pack-2.validator.js +2 -2
- package/generated/item-related-entity-browse-1.d.ts +48 -0
- package/generated/item-related-entity-browse-1.validator.js +1 -0
- package/generated/map-catalog-2-1.d.ts +103 -0
- package/generated/map-catalog-2-1.validator.d.ts +18 -0
- package/generated/map-catalog-2-1.validator.js +1 -0
- package/generated/map-geography.d.ts +79 -0
- package/generated/map-geography.validator.d.ts +18 -0
- package/generated/map-geography.validator.js +1 -0
- package/generated/monster-catalog-2-1.d.ts +253 -0
- package/generated/monster-catalog-2-1.validator.js +17 -0
- package/generated/monster-catalog-2-2.d.ts +332 -0
- package/generated/monster-catalog-2-2.validator.js +17 -0
- package/generated/monster-catalog-2-3.d.ts +339 -0
- package/generated/monster-catalog-2-3.validator.js +17 -0
- package/generated/monster-drop-browse.d.ts +123 -0
- package/generated/monster-drop-browse.validator.js +17 -0
- package/generated/monster-location-browse-1-1.d.ts +79 -0
- package/generated/monster-location-browse-1-1.validator.js +17 -0
- package/generated/monster-location-browse.d.ts +69 -0
- package/generated/monster-location-browse.validator.js +17 -0
- package/generated/product-manifest.d.ts +23 -0
- package/generated/product-manifest.validator.js +1 -1
- package/package.json +38 -2
package/client/monster-client.js
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
import validateCatalog from '../generated/monster-catalog.validator.js';
|
|
2
2
|
import validateCatalogV2 from '../generated/monster-catalog-2.validator.js';
|
|
3
|
-
import
|
|
3
|
+
import validateCatalogV2_1 from '../generated/monster-catalog-2-1.validator.js';
|
|
4
|
+
import validateCatalogV2_2 from '../generated/monster-catalog-2-2.validator.js';
|
|
5
|
+
import validateCatalogV2_3 from '../generated/monster-catalog-2-3.validator.js';
|
|
6
|
+
import validateDropBrowse from '../generated/monster-drop-browse.validator.js';
|
|
7
|
+
import validateLocationBrowse from '../generated/monster-location-browse.validator.js';
|
|
8
|
+
import validateLocationBrowseV1_1 from '../generated/monster-location-browse-1-1.validator.js';
|
|
9
|
+
import { MissingPageError, MissingRecordError, SchemaValidationError, UnsupportedCapabilityError, UnsupportedProductError, assertEnvelopeVersion, assertSameScope, lazyValidator, memoized, openProductContext, rangeDescriptor, recordRangeDescriptor, } from './core.js';
|
|
10
|
+
/**
|
|
11
|
+
* Contract-2 catalog validator that picks the revision's strict schema from the document's
|
|
12
|
+
* own `contractVersion`. Unsupported revisions fail the 2.0 schema with a typed error.
|
|
13
|
+
*/
|
|
14
|
+
const validateCatalogRevision = Object.assign((data) => {
|
|
15
|
+
const version = data?.contractVersion;
|
|
16
|
+
const validator = version === '2.3'
|
|
17
|
+
? validateCatalogV2_3
|
|
18
|
+
: version === '2.2'
|
|
19
|
+
? validateCatalogV2_2
|
|
20
|
+
: version === '2.1'
|
|
21
|
+
? validateCatalogV2_1
|
|
22
|
+
: validateCatalogV2;
|
|
23
|
+
const valid = validator(data);
|
|
24
|
+
validateCatalogRevision.errors = validator.errors;
|
|
25
|
+
return valid;
|
|
26
|
+
}, { errors: undefined });
|
|
4
27
|
const loadDetailPack = lazyValidator(() => import('../generated/monster-pack.validator.js'));
|
|
5
28
|
const loadDetail = lazyValidator(() => import('../generated/monster-detail.validator.js'));
|
|
6
29
|
const loadDetailPackV2 = lazyValidator(() => import('../generated/monster-pack-2.validator.js'));
|
|
@@ -10,9 +33,16 @@ const loadLocationsV2 = lazyValidator(() => import('../generated/monster-locatio
|
|
|
10
33
|
const loadCoreRelationshipsV2 = lazyValidator(() => import('../generated/monster-core-relationship-pack-2.validator.js'));
|
|
11
34
|
const loadEvidence = lazyValidator(() => import('../generated/monster-evidence-pack.validator.js'));
|
|
12
35
|
const loadEvidenceV2 = lazyValidator(() => import('../generated/monster-evidence-pack-2.validator.js'));
|
|
36
|
+
const validateLocationBrowseRevision = Object.assign((data) => {
|
|
37
|
+
const version = data?.contractVersion;
|
|
38
|
+
const validator = version === '1.1' ? validateLocationBrowseV1_1 : validateLocationBrowse;
|
|
39
|
+
const valid = validator(data);
|
|
40
|
+
validateLocationBrowseRevision.errors = validator.errors;
|
|
41
|
+
return valid;
|
|
42
|
+
}, { errors: undefined });
|
|
13
43
|
/** Build a Monster client over an already verified product manifest. */
|
|
14
44
|
export function monsterProductClient(context) {
|
|
15
|
-
const { manifest, contract2, fetchEnvelope } = context;
|
|
45
|
+
const { manifest, contract2, fetchJson, fetchEnvelope } = context;
|
|
16
46
|
if (manifest.productId !== 'monsters')
|
|
17
47
|
throw new UnsupportedProductError(manifest.productId);
|
|
18
48
|
let catalogPromise;
|
|
@@ -26,7 +56,7 @@ export function monsterProductClient(context) {
|
|
|
26
56
|
async function loadCatalog(operation) {
|
|
27
57
|
if (!catalogPromise) {
|
|
28
58
|
catalogPromise = contract2
|
|
29
|
-
? fetchEnvelope(manifest.catalog, 'catalog',
|
|
59
|
+
? fetchEnvelope(manifest.catalog, 'catalog', validateCatalogRevision, operation)
|
|
30
60
|
: fetchEnvelope(manifest.catalog, 'catalog', validateCatalog, operation);
|
|
31
61
|
void catalogPromise.catch(() => { catalogPromise = undefined; });
|
|
32
62
|
}
|
|
@@ -36,6 +66,26 @@ export function monsterProductClient(context) {
|
|
|
36
66
|
}
|
|
37
67
|
return catalog;
|
|
38
68
|
}
|
|
69
|
+
async function loadBrowseArtifact(descriptor, capability, validator, label, operation) {
|
|
70
|
+
if (!(manifest.requiredClientCapabilities ?? []).includes(capability)) {
|
|
71
|
+
throw new UnsupportedCapabilityError('Monster product manifest does not require ' + capability);
|
|
72
|
+
}
|
|
73
|
+
if (!descriptor) {
|
|
74
|
+
throw new UnsupportedCapabilityError('Monster product manifest does not provide ' + label);
|
|
75
|
+
}
|
|
76
|
+
const raw = await fetchJson(descriptor, 'browse', operation);
|
|
77
|
+
if (!validator(raw)) {
|
|
78
|
+
throw new SchemaValidationError(descriptor.path, JSON.stringify(validator.errors ?? []));
|
|
79
|
+
}
|
|
80
|
+
assertSameScope(raw.scope, manifest.scope, descriptor.path);
|
|
81
|
+
return raw;
|
|
82
|
+
}
|
|
83
|
+
async function loadDropBrowse(operation) {
|
|
84
|
+
return loadBrowseArtifact(manifest.dropBrowse, 'monster-drop-browse-v1', validateDropBrowse, 'drop browse artifact', operation);
|
|
85
|
+
}
|
|
86
|
+
async function loadLocationBrowse(operation) {
|
|
87
|
+
return loadBrowseArtifact(manifest.locationBrowse, 'monster-location-browse-v1', validateLocationBrowseRevision, 'location browse artifact', operation);
|
|
88
|
+
}
|
|
39
89
|
async function getDetail(key, operation) {
|
|
40
90
|
const descriptor = recordRangeDescriptor(manifest.detailPacks, key, 'detail', 'Monster');
|
|
41
91
|
if (contract2) {
|
|
@@ -140,6 +190,8 @@ export function monsterProductClient(context) {
|
|
|
140
190
|
return {
|
|
141
191
|
manifest,
|
|
142
192
|
loadCatalog,
|
|
193
|
+
loadDropBrowse,
|
|
194
|
+
loadLocationBrowse,
|
|
143
195
|
getDetail,
|
|
144
196
|
getRelationshipPage,
|
|
145
197
|
getEvidencePage,
|
package/client/monsters.d.ts
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import type { StaticMonsterCatalog } from './monster-client.js';
|
|
1
|
+
import type { MonsterCatalogV2_1 } from '../generated/monster-catalog-2-1.d.ts';
|
|
2
|
+
import type { MonsterCatalogV2_2 } from '../generated/monster-catalog-2-2.d.ts';
|
|
3
|
+
import type { MonsterCatalogV2_3 } from '../generated/monster-catalog-2-3.d.ts';
|
|
4
|
+
import type { MonsterDropBrowseV1 } from '../generated/monster-drop-browse.d.ts';
|
|
5
|
+
import type { MonsterLocationBrowseV1 } from '../generated/monster-location-browse.d.ts';
|
|
6
|
+
import type { MonsterLocationBrowseV1_1 } from '../generated/monster-location-browse-1-1.d.ts';
|
|
7
|
+
import type { StaticMonsterCatalog, StaticMonsterLocationBrowse } from './monster-client.js';
|
|
9
8
|
import { type OpenReleaseOptions } from './release.js';
|
|
9
|
+
export type { MonsterCatalogV2_3 };
|
|
10
10
|
export { isMonsterProductClient, openMonsterProduct } from './monster-client.js';
|
|
11
11
|
export type { StaticMonsterCatalog, StaticMonsterDetail, StaticMonsterEvidencePage, StaticProductClient, } from './monster-client.js';
|
|
12
|
+
export type { MonsterDropBrowseV1, MonsterLocationBrowseV1, MonsterLocationBrowseV1_1 };
|
|
13
|
+
export type { MonsterCatalogV2_1, MonsterCatalogV2_2 };
|
|
12
14
|
export type { OpenReleaseOptions };
|
|
13
15
|
/** Options for the one-shot Monster catalog read: an opened release plus the build to read. */
|
|
14
16
|
export type GetMonsterBrowseOptions = OpenReleaseOptions & {
|
|
15
17
|
readonly buildId: string;
|
|
16
18
|
};
|
|
19
|
+
/** Options for one verified Monster drop browse artifact read. */
|
|
20
|
+
export type GetMonsterDropBrowseOptions = GetMonsterBrowseOptions;
|
|
21
|
+
/** Options for one verified Monster location browse artifact read. */
|
|
22
|
+
export type GetMonsterLocationBrowseOptions = GetMonsterBrowseOptions;
|
|
17
23
|
/**
|
|
18
24
|
* Read one build's verified Monster catalog in a single call.
|
|
19
25
|
*
|
|
@@ -22,3 +28,26 @@ export type GetMonsterBrowseOptions = OpenReleaseOptions & {
|
|
|
22
28
|
* lower-level release client when several domain reads share one release.
|
|
23
29
|
*/
|
|
24
30
|
export declare function getMonsterBrowse(options: GetMonsterBrowseOptions): Promise<StaticMonsterCatalog>;
|
|
31
|
+
/** Read one build's manifest-pinned Monster drop browse artifact without caching or fallback. */
|
|
32
|
+
export declare function getMonsterDropBrowse(options: GetMonsterDropBrowseOptions): Promise<MonsterDropBrowseV1>;
|
|
33
|
+
/** Read one build's manifest-pinned Monster location browse artifact without caching or fallback. */
|
|
34
|
+
export declare function getMonsterLocationBrowse(options: GetMonsterLocationBrowseOptions): Promise<StaticMonsterLocationBrowse>;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve one Monster sprite blob URL from a catalog row's known `sprite` content ID.
|
|
37
|
+
*
|
|
38
|
+
* The blob lives under the same release root as the catalog, so no Media product is
|
|
39
|
+
* opened. Throws `SchemaValidationError` for anything but a lowercase SHA-256 digest.
|
|
40
|
+
*/
|
|
41
|
+
export declare function monsterSpriteUrl(baseUrl: URL | string, contentId: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Narrow a verified catalog to a revision whose rows carry `sprite`. Catalogs 2.1 and
|
|
44
|
+
* 2.2 include it; earlier pins do not. The loose 1.x type keeps a plain field check from
|
|
45
|
+
* narrowing.
|
|
46
|
+
*/
|
|
47
|
+
export declare function hasMonsterSprites(catalog: StaticMonsterCatalog): catalog is MonsterCatalogV2_1 | MonsterCatalogV2_2 | MonsterCatalogV2_3;
|
|
48
|
+
/** Narrow a verified catalog to revisions with drop and location summaries. */
|
|
49
|
+
export declare function hasMonsterBrowseSummaries(catalog: StaticMonsterCatalog): catalog is MonsterCatalogV2_2 | MonsterCatalogV2_3;
|
|
50
|
+
/** Narrow a verified catalog to revision 2.3, whose rows carry geography key unions. */
|
|
51
|
+
export declare function hasMonsterGeography(catalog: StaticMonsterCatalog): catalog is MonsterCatalogV2_3;
|
|
52
|
+
/** Narrow a location browse artifact to revision 1.1, whose entries carry Map geography facts. */
|
|
53
|
+
export declare function hasMonsterLocationGeography(browse: StaticMonsterLocationBrowse): browse is MonsterLocationBrowseV1_1;
|
package/client/monsters.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@mapletip/data/monsters` — Monster browse and Monster product operations.
|
|
3
|
+
*
|
|
4
|
+
* This entry pulls the verified release core and the Monster client (with its catalog
|
|
5
|
+
* validators) and nothing else: Item, Equipment, Media, Quest, static-domain code and
|
|
6
|
+
* Monster detail/relationship/evidence validators stay out of the initial graph.
|
|
7
|
+
*/
|
|
8
|
+
import { resolveMediaContentUrl } from './core.js';
|
|
1
9
|
import { openRelease } from './release.js';
|
|
2
10
|
export { isMonsterProductClient, openMonsterProduct } from './monster-client.js';
|
|
3
11
|
/**
|
|
@@ -12,3 +20,46 @@ export async function getMonsterBrowse(options) {
|
|
|
12
20
|
const monster = await release.openBuild(options.buildId);
|
|
13
21
|
return monster.loadCatalog({ signal: options.signal });
|
|
14
22
|
}
|
|
23
|
+
/** Read one build's manifest-pinned Monster drop browse artifact without caching or fallback. */
|
|
24
|
+
export async function getMonsterDropBrowse(options) {
|
|
25
|
+
const release = await openRelease(options);
|
|
26
|
+
const monster = await release.openBuild(options.buildId);
|
|
27
|
+
return monster.loadDropBrowse({ signal: options.signal });
|
|
28
|
+
}
|
|
29
|
+
/** Read one build's manifest-pinned Monster location browse artifact without caching or fallback. */
|
|
30
|
+
export async function getMonsterLocationBrowse(options) {
|
|
31
|
+
const release = await openRelease(options);
|
|
32
|
+
const monster = await release.openBuild(options.buildId);
|
|
33
|
+
return monster.loadLocationBrowse({ signal: options.signal });
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolve one Monster sprite blob URL from a catalog row's known `sprite` content ID.
|
|
37
|
+
*
|
|
38
|
+
* The blob lives under the same release root as the catalog, so no Media product is
|
|
39
|
+
* opened. Throws `SchemaValidationError` for anything but a lowercase SHA-256 digest.
|
|
40
|
+
*/
|
|
41
|
+
export function monsterSpriteUrl(baseUrl, contentId) {
|
|
42
|
+
return resolveMediaContentUrl(baseUrl, contentId, 'Monster sprite');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Narrow a verified catalog to a revision whose rows carry `sprite`. Catalogs 2.1 and
|
|
46
|
+
* 2.2 include it; earlier pins do not. The loose 1.x type keeps a plain field check from
|
|
47
|
+
* narrowing.
|
|
48
|
+
*/
|
|
49
|
+
export function hasMonsterSprites(catalog) {
|
|
50
|
+
return catalog.format === 'mapletip.monster-catalog-2'
|
|
51
|
+
&& (catalog.contractVersion === '2.1' || catalog.contractVersion === '2.2' || catalog.contractVersion === '2.3');
|
|
52
|
+
}
|
|
53
|
+
/** Narrow a verified catalog to revisions with drop and location summaries. */
|
|
54
|
+
export function hasMonsterBrowseSummaries(catalog) {
|
|
55
|
+
return catalog.format === 'mapletip.monster-catalog-2'
|
|
56
|
+
&& (catalog.contractVersion === '2.2' || catalog.contractVersion === '2.3');
|
|
57
|
+
}
|
|
58
|
+
/** Narrow a verified catalog to revision 2.3, whose rows carry geography key unions. */
|
|
59
|
+
export function hasMonsterGeography(catalog) {
|
|
60
|
+
return catalog.format === 'mapletip.monster-catalog-2' && catalog.contractVersion === '2.3';
|
|
61
|
+
}
|
|
62
|
+
/** Narrow a location browse artifact to revision 1.1, whose entries carry Map geography facts. */
|
|
63
|
+
export function hasMonsterLocationGeography(browse) {
|
|
64
|
+
return browse.format === 'mapletip.monster-location-browse' && browse.contractVersion === '1.1';
|
|
65
|
+
}
|
|
@@ -16,9 +16,9 @@ import { type StaticDomainProductClient } from './static-domains.js';
|
|
|
16
16
|
export { ContractVersionError, IntegrityError, InvalidJsonError, InvalidPathError, MissingPageError, MissingRecordError, RequestError, SchemaValidationError, ScopeError, SecureContextRequiredError, StaticClientError, UnknownBuildError, UnsupportedCapabilityError, UnsupportedProductError, resolveMediaUrl, verifyBlob, } from './core.js';
|
|
17
17
|
export type { GetRelationshipOptions, IntegrityDescriptor, OpenProductOptions, OperationOptions, ProductIdentity, ProductManifestDescriptor, ProductScope, RequestKind, RequestLogEntry, RequestLogHook, StaticProductManifest, } from './core.js';
|
|
18
18
|
export { isMonsterProductClient, openMonsterProduct } from './monster-client.js';
|
|
19
|
-
export type { StaticMonsterCatalog, StaticMonsterDetail, StaticMonsterEvidencePage, StaticProductClient, } from './monster-client.js';
|
|
20
|
-
export { getItemBrowse, isItemProductClient, itemIconUrl, openItemProduct } from './items.js';
|
|
21
|
-
export type { GetItemBrowseOptions, ItemBrowseCoverage, ItemBrowsePack, ItemBrowseRecord, ItemBrowseRow, StaticItemBrowse, StaticItemCatalog, StaticItemDetail, StaticItemProductClient, } from './items.js';
|
|
19
|
+
export type { StaticMonsterCatalog, StaticMonsterDetail, StaticMonsterEvidencePage, StaticMonsterLocationBrowse, StaticProductClient, } from './monster-client.js';
|
|
20
|
+
export { getItemBrowse, getItemRelatedEntities, hasItemPlayerFacts, isItemProductClient, itemIconUrl, openItemProduct, } from './items.js';
|
|
21
|
+
export type { GetItemBrowseOptions, GetItemRelatedEntitiesOptions, ItemBrowseBuff, ItemBrowseBuffEffect, ItemBrowseBuffStat, ItemBrowseBuffUnit, ItemBrowseCoverage, ItemBrowseCoverageState, ItemBrowsePlayerFactCoverage, ItemBrowsePack, ItemBrowseJobFamily, ItemBrowseLevelRange, ItemBrowseRecovery, ItemBrowseRequirement, ItemBrowseRelationshipKind, ItemBrowseRecord, ItemBrowseRow, ItemRelatedEntityBrowsePack, ItemRelatedEntityTarget, StaticItemBrowse, StaticItemBrowseV2_0, StaticItemBrowseV2_1, StaticItemCatalog, StaticItemDetail, StaticItemProductClient, } from './items.js';
|
|
22
22
|
export { isEquipmentProductClient, openEquipmentProduct } from './equipment.js';
|
|
23
23
|
export type { StaticEquipmentCatalog, StaticEquipmentDetail, StaticEquipmentProductClient, } from './equipment.js';
|
|
24
24
|
export { isMediaProductClient, openMediaProduct } from './media.js';
|
|
@@ -28,8 +28,10 @@ export type { QuestAuxiliaryPack, QuestAuxiliaryPage, QuestBrowsePack, QuestBrow
|
|
|
28
28
|
export type { StaticDomainCatalog, StaticDomainCatalogRecord, StaticDomainDetailRecord, StaticDomainFactState, StaticDomainProductClient, StaticDomainSourceIdentity, } from './static-domains.js';
|
|
29
29
|
export { openRelease, resolveTargetAvailability } from './release.js';
|
|
30
30
|
export type { OpenReleaseOptions, ReleaseProductDescriptor, StaticReleaseBuild, StaticReleaseClient, TargetAvailability, } from './release.js';
|
|
31
|
-
export { getMonsterBrowse } from './monsters.js';
|
|
32
|
-
export type { GetMonsterBrowseOptions } from './monsters.js';
|
|
31
|
+
export { getMonsterBrowse, getMonsterDropBrowse, getMonsterLocationBrowse, hasMonsterGeography, hasMonsterLocationGeography, hasMonsterBrowseSummaries, hasMonsterSprites, monsterSpriteUrl, } from './monsters.js';
|
|
32
|
+
export type { GetMonsterBrowseOptions, GetMonsterDropBrowseOptions, GetMonsterLocationBrowseOptions, MonsterDropBrowseV1, MonsterLocationBrowseV1, MonsterLocationBrowseV1_1, MonsterCatalogV2_3, } from './monsters.js';
|
|
33
|
+
export { getMapGeography, isMapGeographyModel, isMapProductClient, openMapProduct } from './maps.js';
|
|
34
|
+
export type { GetMapGeographyOptions, MapGeographyModel, StaticMapProductClient } from './maps.js';
|
|
33
35
|
export type AnyProductClient = StaticProductClient | StaticMediaProductClient | StaticQuestProductClient | StaticItemProductClient | StaticEquipmentProductClient | StaticDomainProductClient;
|
|
34
36
|
/**
|
|
35
37
|
* Open one pinned product of any supported domain.
|
package/client/static-client.js
CHANGED
|
@@ -15,12 +15,13 @@ import { questProductClient } from './quests.js';
|
|
|
15
15
|
import { staticDomainProductClient } from './static-domains.js';
|
|
16
16
|
export { ContractVersionError, IntegrityError, InvalidJsonError, InvalidPathError, MissingPageError, MissingRecordError, RequestError, SchemaValidationError, ScopeError, SecureContextRequiredError, StaticClientError, UnknownBuildError, UnsupportedCapabilityError, UnsupportedProductError, resolveMediaUrl, verifyBlob, } from './core.js';
|
|
17
17
|
export { isMonsterProductClient, openMonsterProduct } from './monster-client.js';
|
|
18
|
-
export { getItemBrowse, isItemProductClient, itemIconUrl, openItemProduct } from './items.js';
|
|
18
|
+
export { getItemBrowse, getItemRelatedEntities, hasItemPlayerFacts, isItemProductClient, itemIconUrl, openItemProduct, } from './items.js';
|
|
19
19
|
export { isEquipmentProductClient, openEquipmentProduct } from './equipment.js';
|
|
20
20
|
export { isMediaProductClient, openMediaProduct } from './media.js';
|
|
21
21
|
export { isQuestProductClient, openQuestProduct } from './quests.js';
|
|
22
22
|
export { openRelease, resolveTargetAvailability } from './release.js';
|
|
23
|
-
export { getMonsterBrowse } from './monsters.js';
|
|
23
|
+
export { getMonsterBrowse, getMonsterDropBrowse, getMonsterLocationBrowse, hasMonsterGeography, hasMonsterLocationGeography, hasMonsterBrowseSummaries, hasMonsterSprites, monsterSpriteUrl, } from './monsters.js';
|
|
24
|
+
export { getMapGeography, isMapGeographyModel, isMapProductClient, openMapProduct } from './maps.js';
|
|
24
25
|
/**
|
|
25
26
|
* Open one pinned product of any supported domain.
|
|
26
27
|
*
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* envelopes are checked against the same contract/scope rules as every other pack.
|
|
5
5
|
*/
|
|
6
6
|
import { type OpenProductOptions, type OperationOptions, type ProductScope, type StaticProductManifest, type VerifiedProductContext } from './core.js';
|
|
7
|
+
import type { MapGeographyFact } from '../generated/map-catalog-2-1.d.ts';
|
|
8
|
+
import type { MapGeographyModel } from '../generated/map-geography.d.ts';
|
|
9
|
+
export type { MapGeographyFact, MapGeographyModel };
|
|
7
10
|
export type StaticDomainFactState = {
|
|
8
11
|
readonly state: 'known';
|
|
9
12
|
readonly value: string;
|
|
@@ -24,10 +27,11 @@ export interface StaticDomainCatalogRecord {
|
|
|
24
27
|
readonly sourceIdentity: StaticDomainSourceIdentity;
|
|
25
28
|
readonly name: StaticDomainFactState;
|
|
26
29
|
readonly facts: Readonly<Record<string, unknown>>;
|
|
30
|
+
readonly geography?: MapGeographyFact;
|
|
27
31
|
}
|
|
28
32
|
export interface StaticDomainCatalog {
|
|
29
33
|
readonly format: 'mapletip.domain-catalog/1';
|
|
30
|
-
readonly contractVersion:
|
|
34
|
+
readonly contractVersion: '2.0' | '2.1';
|
|
31
35
|
readonly scope: ProductScope;
|
|
32
36
|
readonly domain: string;
|
|
33
37
|
readonly coverage: 'partial';
|
|
@@ -40,8 +44,11 @@ export interface StaticDomainDetailRecord extends StaticDomainCatalogRecord {
|
|
|
40
44
|
export interface StaticDomainProductClient {
|
|
41
45
|
readonly manifest: StaticProductManifest;
|
|
42
46
|
loadCatalog(options?: OperationOptions): Promise<StaticDomainCatalog>;
|
|
47
|
+
loadGeography(options?: OperationOptions): Promise<MapGeographyModel>;
|
|
43
48
|
getDetail(key: string, options?: OperationOptions): Promise<StaticDomainDetailRecord>;
|
|
44
49
|
}
|
|
50
|
+
/** Type guard for the build-scoped, labeled Map geography read model. */
|
|
51
|
+
export declare function isMapGeographyModel(value: unknown): value is MapGeographyModel;
|
|
45
52
|
/** Build a static domain client over an already verified product manifest. */
|
|
46
53
|
export declare function staticDomainProductClient(context: VerifiedProductContext): StaticDomainProductClient;
|
|
47
54
|
/** Open one pinned static domain product. */
|
package/client/static-domains.js
CHANGED
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
* cash-shop, avatars). These products carry no generated Ajv validators; their
|
|
4
4
|
* envelopes are checked against the same contract/scope rules as every other pack.
|
|
5
5
|
*/
|
|
6
|
-
import { MissingRecordError, SchemaValidationError, UnsupportedProductError, assertEnvelopeVersion, assertSameScope, isStaticDomain, memoized, openProductContext, recordRangeDescriptor, } from './core.js';
|
|
6
|
+
import { MissingRecordError, SchemaValidationError, UnsupportedCapabilityError, UnsupportedProductError, assertEnvelopeVersion, assertSameScope, isStaticDomain, memoized, openProductContext, recordRangeDescriptor, } from './core.js';
|
|
7
|
+
import validateMapCatalogV2_1 from '../generated/map-catalog-2-1.validator.js';
|
|
8
|
+
import validateMapGeography from '../generated/map-geography.validator.js';
|
|
9
|
+
/** Type guard for the build-scoped, labeled Map geography read model. */
|
|
10
|
+
export function isMapGeographyModel(value) {
|
|
11
|
+
return validateMapGeography(value);
|
|
12
|
+
}
|
|
7
13
|
function asObject(value) {
|
|
8
14
|
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
9
15
|
? value
|
|
@@ -14,7 +20,8 @@ function assertDomainCatalog(value, path, manifest) {
|
|
|
14
20
|
const records = object?.records;
|
|
15
21
|
const scope = asObject(object?.scope);
|
|
16
22
|
if (!object || object.format !== 'mapletip.domain-catalog/1'
|
|
17
|
-
|| object.contractVersion !== '2.0'
|
|
23
|
+
|| (object.contractVersion !== '2.0'
|
|
24
|
+
&& !(manifest.productId === 'maps' && object.contractVersion === '2.1'))
|
|
18
25
|
|| object.domain !== manifest.productId
|
|
19
26
|
|| object.coverage !== 'partial'
|
|
20
27
|
|| !scope || scope.family_id !== manifest.scope.family_id || scope.build_id !== manifest.scope.build_id
|
|
@@ -23,6 +30,9 @@ function assertDomainCatalog(value, path, manifest) {
|
|
|
23
30
|
|| object.recordCount !== records.length) {
|
|
24
31
|
throw new SchemaValidationError(path, 'invalid MapleKit normalized domain catalog envelope');
|
|
25
32
|
}
|
|
33
|
+
if (object.contractVersion === '2.1' && !validateMapCatalogV2_1(value)) {
|
|
34
|
+
throw new SchemaValidationError(path, JSON.stringify(validateMapCatalogV2_1.errors ?? []));
|
|
35
|
+
}
|
|
26
36
|
let previous = '';
|
|
27
37
|
for (const recordValue of records) {
|
|
28
38
|
const record = asObject(recordValue);
|
|
@@ -105,7 +115,21 @@ export function staticDomainProductClient(context) {
|
|
|
105
115
|
throw new MissingRecordError(key, manifest.productId);
|
|
106
116
|
return detail;
|
|
107
117
|
}
|
|
108
|
-
|
|
118
|
+
async function loadGeography(operation) {
|
|
119
|
+
const capability = 'map-geography-v1';
|
|
120
|
+
if (manifest.productId !== 'maps'
|
|
121
|
+
|| !(manifest.requiredClientCapabilities ?? []).includes(capability)
|
|
122
|
+
|| !manifest.geography) {
|
|
123
|
+
throw new UnsupportedCapabilityError('Maps product manifest does not provide map-geography-v1');
|
|
124
|
+
}
|
|
125
|
+
const raw = await fetchJson(manifest.geography, 'browse', operation);
|
|
126
|
+
if (!isMapGeographyModel(raw)) {
|
|
127
|
+
throw new SchemaValidationError(manifest.geography.path, JSON.stringify(validateMapGeography.errors ?? []));
|
|
128
|
+
}
|
|
129
|
+
assertSameScope(raw.scope, manifest.scope, manifest.geography.path);
|
|
130
|
+
return raw;
|
|
131
|
+
}
|
|
132
|
+
return { manifest, loadCatalog, loadGeography, getDetail };
|
|
109
133
|
}
|
|
110
134
|
/** Open one pinned static domain product. */
|
|
111
135
|
export async function openStaticDomainProduct(options) {
|
|
@@ -4,6 +4,28 @@
|
|
|
4
4
|
* Coverage state for one browse relationship or the Scroll tier facet.
|
|
5
5
|
*/
|
|
6
6
|
export type ItemBrowseCoverageState = "complete" | "partial" | "unsupported";
|
|
7
|
+
/**
|
|
8
|
+
* Closed player-stat vocabulary for consumable buffs.
|
|
9
|
+
*/
|
|
10
|
+
export type ItemBrowseBuffStat =
|
|
11
|
+
| "weaponAttack"
|
|
12
|
+
| "magicAttack"
|
|
13
|
+
| "weaponDefense"
|
|
14
|
+
| "magicDefense"
|
|
15
|
+
| "accuracy"
|
|
16
|
+
| "avoidability"
|
|
17
|
+
| "speed"
|
|
18
|
+
| "jump"
|
|
19
|
+
| "criticalRate"
|
|
20
|
+
| "criticalDamage"
|
|
21
|
+
| "maxHp"
|
|
22
|
+
| "maxMp"
|
|
23
|
+
| "itemDropRate"
|
|
24
|
+
| "mesoDropRate";
|
|
25
|
+
/**
|
|
26
|
+
* Whether a buff effect is an absolute stat delta or a percentage.
|
|
27
|
+
*/
|
|
28
|
+
export type ItemBrowseBuffUnit = "flat" | "percent";
|
|
7
29
|
/**
|
|
8
30
|
* Positive source-backed Item behavior.
|
|
9
31
|
*/
|
|
@@ -34,6 +56,10 @@ export type CoverageKey = string;
|
|
|
34
56
|
* Canonical non-equipment Item class.
|
|
35
57
|
*/
|
|
36
58
|
export type ItemBrowseClass = "consume" | "etc" | "setup" | "cash" | "pet";
|
|
59
|
+
/**
|
|
60
|
+
* Job family named by a source-backed Item requirement.
|
|
61
|
+
*/
|
|
62
|
+
export type ItemBrowseJobFamily = "beginner" | "warrior" | "magician" | "bowman" | "thief" | "pirate";
|
|
37
63
|
/**
|
|
38
64
|
* Named or typed Scroll mechanic.
|
|
39
65
|
*/
|
|
@@ -102,7 +128,7 @@ export type ItemBrowseType =
|
|
|
102
128
|
* Bounded pack of compact browse rows keyed by Item public key.
|
|
103
129
|
*/
|
|
104
130
|
export interface ItemBrowsePack {
|
|
105
|
-
contractVersion: "2.0";
|
|
131
|
+
contractVersion: "2.0" | "2.1";
|
|
106
132
|
coverage: ItemBrowseCoverage;
|
|
107
133
|
format: "item-browse-pack/1";
|
|
108
134
|
records: {
|
|
@@ -114,9 +140,27 @@ export interface ItemBrowsePack {
|
|
|
114
140
|
* Build-level coverage for the browse product.
|
|
115
141
|
*/
|
|
116
142
|
export interface ItemBrowseCoverage {
|
|
143
|
+
/**
|
|
144
|
+
* Per-build availability of the sparse player-facing browse facts.
|
|
145
|
+
* Missing in Item Browse 2.0 documents; present in 2.1 documents.
|
|
146
|
+
*/
|
|
147
|
+
playerFacts?: ItemBrowsePlayerFactCoverage | null;
|
|
117
148
|
relationships: ItemBrowseRelationshipCoverage;
|
|
118
149
|
scrollTier: ItemBrowseCoverageState;
|
|
119
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Per-field source availability for player-facing browse facts in one build.
|
|
153
|
+
*/
|
|
154
|
+
export interface ItemBrowsePlayerFactCoverage {
|
|
155
|
+
buff: ItemBrowseCoverageState;
|
|
156
|
+
flatRecovery: ItemBrowseCoverageState;
|
|
157
|
+
levelRange: ItemBrowseCoverageState;
|
|
158
|
+
maxStack: ItemBrowseCoverageState;
|
|
159
|
+
percentRecovery: ItemBrowseCoverageState;
|
|
160
|
+
requirementJobs: ItemBrowseCoverageState;
|
|
161
|
+
requirementLevel: ItemBrowseCoverageState;
|
|
162
|
+
sellPrice: ItemBrowseCoverageState;
|
|
163
|
+
}
|
|
120
164
|
/**
|
|
121
165
|
* Per-relationship coverage for one build.
|
|
122
166
|
*/
|
|
@@ -133,21 +177,52 @@ export interface ItemBrowseRelationshipCoverage {
|
|
|
133
177
|
* One compact Item Browse row.
|
|
134
178
|
*/
|
|
135
179
|
export interface ItemBrowseRecord {
|
|
180
|
+
buff?: ItemBrowseBuff | null;
|
|
136
181
|
family?: string | null;
|
|
137
182
|
functions?: ItemBrowseFunction[];
|
|
138
183
|
icon: CatalogFact;
|
|
139
184
|
itemClass: ItemBrowseClass;
|
|
185
|
+
levelRange?: ItemBrowseLevelRange | null;
|
|
186
|
+
maxStack?: number | null;
|
|
140
187
|
name: CatalogFact;
|
|
141
188
|
petFood?: ItemBrowsePetFood | null;
|
|
142
189
|
projectileAttack?: number | null;
|
|
143
190
|
questFlag?: boolean;
|
|
144
191
|
recovery?: ItemBrowseRecovery | null;
|
|
145
192
|
relationships?: ItemBrowseRelationshipCounts;
|
|
193
|
+
requirement?: ItemBrowseRequirement | null;
|
|
146
194
|
scroll?: ItemBrowseScroll | null;
|
|
147
195
|
seatingRecovery?: ItemBrowseSeatingRecovery | null;
|
|
196
|
+
/**
|
|
197
|
+
* Sparse facts. Omission means unknown unless coverage says unsupported.
|
|
198
|
+
*/
|
|
199
|
+
sellPrice?: number | null;
|
|
148
200
|
sourceId: string;
|
|
149
201
|
types?: ItemBrowseType[];
|
|
150
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Recognized consumable buffs and their optional source duration.
|
|
205
|
+
*/
|
|
206
|
+
export interface ItemBrowseBuff {
|
|
207
|
+
durationSeconds?: number | null;
|
|
208
|
+
effects: ItemBrowseBuffEffect[];
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* One recognized source-backed consumable buff effect.
|
|
212
|
+
*/
|
|
213
|
+
export interface ItemBrowseBuffEffect {
|
|
214
|
+
stat: ItemBrowseBuffStat;
|
|
215
|
+
unit: ItemBrowseBuffUnit;
|
|
216
|
+
value: number;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Separate level-band and requirement-level adjustment facts.
|
|
220
|
+
*/
|
|
221
|
+
export interface ItemBrowseLevelRange {
|
|
222
|
+
monsterLevelMax?: number | null;
|
|
223
|
+
monsterLevelMin?: number | null;
|
|
224
|
+
requirementLevelDelta?: number | null;
|
|
225
|
+
}
|
|
151
226
|
/**
|
|
152
227
|
* Pet-food effect values and the Pet items they target.
|
|
153
228
|
*/
|
|
@@ -179,6 +254,13 @@ export interface ItemBrowseRelationshipCounts {
|
|
|
179
254
|
"quest-reward"?: number | null;
|
|
180
255
|
"used-in-recipe"?: number | null;
|
|
181
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Requirement facts. The optional fields are sparse; absence means the source value is unknown.
|
|
259
|
+
*/
|
|
260
|
+
export interface ItemBrowseRequirement {
|
|
261
|
+
jobs?: ItemBrowseJobFamily[];
|
|
262
|
+
level?: number | null;
|
|
263
|
+
}
|
|
182
264
|
/**
|
|
183
265
|
* Scroll facts derived from a typed upgrade row and its source title.
|
|
184
266
|
*/
|