Compare commits

...

1 Commits

Author SHA1 Message Date
Tomáš Mládek 52fc8e73e9 wip
ci/woodpecker/push/woodpecker Pipeline failed Details
2023-11-26 12:41:38 +01:00
4 changed files with 45 additions and 21 deletions

View File

@ -14,6 +14,7 @@ import type {
StoreInfo,
VaultInfo,
} from "./types";
import { asAddress } from "./types";
import type { UpEndWasmExtensions, AddressComponents } from "./wasm";
import debug from "debug";
const dbg = debug("upend:api");
@ -43,7 +44,7 @@ export class UpEndApi {
return this.instanceUrl + "/api";
}
public async fetchEntity(address: string): Promise<UpObject> {
public async fetchEntity(address: Address): Promise<UpObject> {
dbg("Fetching Entity %s", address);
const entityFetch = await fetch(`${this.apiUrl}/obj/${address}`);
const entityResult = (await entityFetch.json()) as EntityListing;
@ -51,11 +52,11 @@ export class UpEndApi {
return entityListing.getObject(address);
}
public async fetchEntry(address: string) {
public async fetchEntry(address: Address) {
dbg("Fetching entry %s", address);
const response = await fetch(`${this.apiUrl}/raw/${address}`);
const data = await response.json();
const listing = new UpListing({ address: data });
const listing = new UpListing({ [address]: data });
return listing.entries[0];
}
@ -103,7 +104,8 @@ export class UpEndApi {
body: JSON.stringify(input),
});
return await response.json();
const [entry, entity] = await response.json();
return [entry, entity].map(asAddress) as PutResult;
}
public async putEntityAttribute(
@ -212,12 +214,12 @@ export class UpEndApi {
| { url: string }
| { urlContent: string }
| ADDRESS_TYPE
): Promise<string> {
): Promise<Address> {
let response: Response;
if (typeof input === "string") {
if (this.wasmExtensions) {
await this.wasmExtensions.init();
return this.wasmExtensions.AddressTypeConstants[input];
return asAddress(this.wasmExtensions.AddressTypeConstants[input]);
}
response = await fetch(`${this.apiUrl}/address?type=${input}`);
} else {
@ -237,7 +239,7 @@ export class UpEndApi {
}
const result = await response.json();
dbg("Address for %o = %s", input, result);
return result;
return asAddress(result);
}
public async addressToComponents(

View File

@ -1,4 +1,5 @@
import type { IEntry, IValue, ListingResult } from "./types";
import type { Address, IEntry, IValue, ListingResult } from "./types";
import { asAddress } from "./types";
export { UpEndApi } from "./api";
export { Query } from "./query";
@ -8,7 +9,7 @@ export class UpListing {
constructor(listing: ListingResult) {
this.entries = Object.entries(listing).map(
(lr) => new UpEntry(...lr, this)
([address, entry]) => new UpEntry(asAddress(address), entry, this)
);
}
@ -21,15 +22,15 @@ export class UpListing {
return result;
}
public getObject(address: string) {
public getObject(address: Address) {
if (!this._objects[address]) {
this._objects[address] = new UpObject(address, this);
}
return this._objects[address];
}
public get entities(): string[] {
return Array.from(new Set(this.entries.map((e) => `@${e.entity}`)));
public get entities(): Address[] {
return Array.from(new Set(this.entries.map((e) => asAddress(e.entity))));
}
public get attributes(): string[] {
@ -42,10 +43,10 @@ export class UpListing {
}
export class UpObject {
public readonly address: string;
public readonly address: Address;
public listing: UpListing | undefined;
constructor(address: string, listing?: UpListing) {
constructor(address: Address, listing?: UpListing) {
this.address = address;
this.listing = listing;
}
@ -106,13 +107,13 @@ export class UpObject {
}
export class UpEntry extends UpObject implements IEntry {
entity: string;
entity: Address;
attribute: string;
value: IValue;
provenance: string;
timestamp: string;
constructor(address: string, entry: IEntry, listing: UpListing) {
constructor(address: Address, entry: IEntry, listing: UpListing) {
super(address, listing);
this.entity = entry.entity;

View File

@ -1,5 +1,16 @@
import test from "ava";
import { Any, Query, Variable } from "./query";
import { asAddress, isAddress } from "./types";
test("address check", (t) => {
const address = "@address";
t.is(isAddress(address), true);
});
test("address conversion", (t) => {
t.is(asAddress("address"), "@address");
t.is(asAddress("@address"), "@address");
});
test("query matches simple", (t) => {
const query = Query.matches("entity", "attribute", "value");

View File

@ -1,9 +1,19 @@
export type Address = string;
export type Address = `@${string}`;
export type ADDRESS_TYPE = "Hash" | "Uuid" | "Attribute" | "Url";
export type VALUE_TYPE = "Address" | "String" | "Number" | "Invalid";
export function isAddress(address: string): address is Address {
return address.startsWith("@");
return address.match(/^@[0-9a-zA-Z]+$/) !== null;
}
export function asAddress(address: string): Address {
const result = address.startsWith("@") ? address : `@${address}`;
if (!isAddress(result)) {
throw new Error(`Invalid address: ${address}`);
}
return result;
}
/**
@ -25,7 +35,7 @@ export interface IEntry {
export type IValue =
| {
t: "Address";
c: string;
c: Address;
}
| {
t: "String";
@ -63,11 +73,11 @@ export type PutInput =
| { entity: InAddress };
export interface ListingResult {
[key: string]: IEntry;
[key: Address]: IEntry;
}
// entry address, entity address address
export type PutResult = [string | undefined, string];
export type PutResult = [Address | undefined, Address];
// export type OrderedListing = [Address, IEntry][];