'use strict'; const assert=require('assert/strict'); const vm=require('vm'); const {read,functionSource,buildMeta}=require('./helpers/app-source'); const SharedContracts=require('../shared-contracts'); const ServerContracts=require('../server'); const packageVersion=JSON.parse(read('package.json')).version; assert.equal(buildMeta.PACKAGE_VERSION,packageVersion); assert.deepEqual( SharedContracts.normalizeSpecialMechanics(['internalGate','warp','crossing','lock','warp','invalid']), ['crossing','internalGate','lock','warp'] ); assert.deepEqual( ServerContracts.sanitizeWorldGlobal({specialMechanicsSeen:['internalGate','warp','invalid']},{global:{}}).specialMechanicsSeen, ['internalGate','warp'] ); const catalog=JSON.parse(read('store-catalog.json')); const catalogMap=new Map(catalog.map(item=>[item.id,item])); const generatedExpected=`'use strict';\n// Generated from store-catalog.json by scripts/generate-store-catalog.js. Do not edit.\nglobalThis.BendStoreCatalog=Object.freeze(${JSON.stringify(catalog)}.map(item=>Object.freeze(item)));\n`; assert.equal(read('store-catalog.generated.js'),generatedExpected,'Browser store catalog is stale; run the catalog generator'); const generatedContext={};vm.createContext(generatedContext);vm.runInContext(generatedExpected,generatedContext); assert.deepEqual(JSON.parse(JSON.stringify(generatedContext.BendStoreCatalog)),catalog); const fixtures=[ {purchaseId:'purchase:1',boardId:'B0',itemId:'score-lens',buyer:' Alice Example ',boughtAt:100,paidCost:200000}, {purchaseId:'purchase:1',boardId:'B1',itemId:'score-lens',buyer:'duplicate-id',boughtAt:101,paidCost:200000}, {purchaseId:'purchase:2',boardId:'B0',itemId:'score-lens',buyer:'duplicate-item',boughtAt:102,paidCost:200000}, {purchaseId:'purchase:3',boardId:'B01',itemId:'score-lens',buyer:'bad-board',boughtAt:103,paidCost:200000}, {purchaseId:'purchase:4',boardId:'B2',itemId:'cursor-face-1f600',buyer:'123456789012345678901234567890',boughtAt:104,paidCost:Number.MAX_SAFE_INTEGER}, {purchaseId:'bad purchase',boardId:'B3',itemId:'score-lens',buyer:'bad-id',boughtAt:105,paidCost:200000} ]; const clientContext={ SharedContracts, storeItem:id=>catalogMap.get(String(id||''))||null, MAX_SCORE:Number.MAX_SAFE_INTEGER, DEFAULT_PLAYER_NAME:'旅人' }; vm.createContext(clientContext); vm.runInContext(`${functionSource('normalizePlayerPurchases')}\nthis.normalizePlayerPurchases=normalizePlayerPurchases;`,clientContext); const client=JSON.parse(JSON.stringify(clientContext.normalizePlayerPurchases(fixtures))); const server=ServerContracts.normalizePlayerPurchases(fixtures); assert.deepEqual(client,server,'Client and server purchase normalization diverged'); assert.equal(client.length,2); assert.equal(client[0].buyer,'Alice Example'); assert.equal(client[1].buyer.length,24); assert.equal(client[1].paidCost,Number.MAX_SAFE_INTEGER); const runtimeContext={globalThis:null};runtimeContext.globalThis=runtimeContext;vm.createContext(runtimeContext);vm.runInContext(read('runtime-config.js'),runtimeContext); assert.equal(runtimeContext.BendRuntimeConfig.cloudApi,false,'Static/file mode must not probe the cloud API'); console.log('Canonical build, store, mechanics, runtime mode, and purchase contracts passed');