@sneat/extension-yardius-contract 0.1.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/dist/index.d.ts +1 -0
- package/dist/index.js +9 -0
- package/dist/lib/assetus-visibility.d.ts +2 -0
- package/dist/lib/assetus-visibility.js +19 -0
- package/dist/lib/borrow-state.d.ts +5 -0
- package/dist/lib/borrow-state.js +49 -0
- package/dist/lib/giveaway-state.d.ts +5 -0
- package/dist/lib/giveaway-state.js +36 -0
- package/dist/lib/index.d.ts +9 -0
- package/dist/lib/index.js +9 -0
- package/dist/lib/listing-request.d.ts +11 -0
- package/dist/lib/listing-request.js +17 -0
- package/dist/lib/listing-visibility.d.ts +7 -0
- package/dist/lib/listing-visibility.js +44 -0
- package/dist/lib/listing.d.ts +22 -0
- package/dist/lib/listing.js +3 -0
- package/dist/lib/listings-endpoint.d.ts +12 -0
- package/dist/lib/listings-endpoint.js +1 -0
- package/dist/lib/state-transitions.d.ts +2 -0
- package/dist/lib/state-transitions.js +7 -0
- package/dist/lib/transaction-log.d.ts +8 -0
- package/dist/lib/transaction-log.js +14 -0
- package/package.json +37 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib/index.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// @sneat/extension-yardius-contract — frozen cross-repo contract surface for the yardius extension.
|
|
2
|
+
//
|
|
3
|
+
// Shared DTOs (listings, transaction-log entries, request/claim shapes, the
|
|
4
|
+
// listings-endpoint contract), lifecycle state enums with their legal
|
|
5
|
+
// transition tables, and the listing-visibility ceiling mapping are exported
|
|
6
|
+
// from here so that both the sneat-go backend models and the Sneat super-app
|
|
7
|
+
// extension libs resolve every shared model from this single package. No
|
|
8
|
+
// consumer may re-declare these.
|
|
9
|
+
export * from './lib/index.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// The Assetus asset-visibility values, mirrored here as wire values so the
|
|
2
|
+
// listing-visibility ceiling (see `listing-visibility.ts`) can be encoded as
|
|
3
|
+
// shared data with zero runtime dependencies.
|
|
4
|
+
//
|
|
5
|
+
// Source of truth for the VALUES is the pinned assetus-mvp contract
|
|
6
|
+
// (`AssetVisibility` in the `@sneat/extension-assetus-contract` lib):
|
|
7
|
+
// spec display names `Private` / `Family` / `Friends` / `Friends of Friends` /
|
|
8
|
+
// `Specific Space` / `Public` are persisted as the lowercase snake_case wire
|
|
9
|
+
// values below. Yardius only READS asset visibility (REQ
|
|
10
|
+
// assetus-write-boundary) — this type exists so both the Yardius frontend and
|
|
11
|
+
// backend consume the ceiling mapping from this single package.
|
|
12
|
+
export const ASSETUS_VISIBILITIES = [
|
|
13
|
+
'private',
|
|
14
|
+
'family',
|
|
15
|
+
'friends',
|
|
16
|
+
'friends_of_friends',
|
|
17
|
+
'specific_space',
|
|
18
|
+
'public',
|
|
19
|
+
];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { StateTransitionTable } from './state-transitions.js';
|
|
2
|
+
export declare const BORROW_STATES: readonly ["available", "requested", "approved", "borrowed", "returned", "closed"];
|
|
3
|
+
export type BorrowState = (typeof BORROW_STATES)[number];
|
|
4
|
+
export declare const BORROW_STATE_TRANSITIONS: StateTransitionTable<BorrowState>;
|
|
5
|
+
export declare function canTransitionBorrow(from: BorrowState, to: BorrowState): boolean;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { canTransition } from './state-transitions.js';
|
|
2
|
+
// Borrow-listing lifecycle states, per REQ borrow-lifecycle (spec display
|
|
3
|
+
// names `Available → Requested → Approved → Borrowed → Returned → Closed`,
|
|
4
|
+
// persisted as the wire values below):
|
|
5
|
+
// - 'available' — open, no pending requests;
|
|
6
|
+
// - 'requested' — ≥1 request pending; the Listing stays visible and accepts
|
|
7
|
+
// further requests;
|
|
8
|
+
// - 'approved' — a member of the owning Space approved exactly one request;
|
|
9
|
+
// all other pending requests are automatically declined and no further
|
|
10
|
+
// requests are accepted;
|
|
11
|
+
// - 'borrowed' — a member of the owning Space confirmed handover;
|
|
12
|
+
// - 'returned' — a member of the owning Space confirmed the item is back;
|
|
13
|
+
// - 'closed' — terminal; immediately follows 'returned' (or an
|
|
14
|
+
// owner-cancel — see REQ owner-cancel).
|
|
15
|
+
export const BORROW_STATES = [
|
|
16
|
+
'available',
|
|
17
|
+
'requested',
|
|
18
|
+
'approved',
|
|
19
|
+
'borrowed',
|
|
20
|
+
'returned',
|
|
21
|
+
'closed',
|
|
22
|
+
];
|
|
23
|
+
// The legal borrow transitions, per REQ borrow-lifecycle + REQ owner-cancel.
|
|
24
|
+
// Any transition not listed here MUST be rejected.
|
|
25
|
+
//
|
|
26
|
+
// available → requested first request arrives
|
|
27
|
+
// available → closed owner cancels (before 'borrowed' — legal)
|
|
28
|
+
// requested → approved owner approves exactly one request
|
|
29
|
+
// requested → available the only pending request is withdrawn
|
|
30
|
+
// requested → closed owner cancels; all pending requests declined
|
|
31
|
+
// approved → borrowed owner confirms handover
|
|
32
|
+
// approved → closed owner cancels (still before 'borrowed')
|
|
33
|
+
// borrowed → returned owner confirms the item is back; a 'borrowed'
|
|
34
|
+
// Listing MUST NOT be cancellable — 'returned' is
|
|
35
|
+
// its only exit
|
|
36
|
+
// returned → closed immediate, automatic
|
|
37
|
+
// closed → (terminal)
|
|
38
|
+
export const BORROW_STATE_TRANSITIONS = {
|
|
39
|
+
available: ['requested', 'closed'],
|
|
40
|
+
requested: ['approved', 'available', 'closed'],
|
|
41
|
+
approved: ['borrowed', 'closed'],
|
|
42
|
+
borrowed: ['returned'],
|
|
43
|
+
returned: ['closed'],
|
|
44
|
+
closed: [],
|
|
45
|
+
};
|
|
46
|
+
// True when `from → to` is a legal borrow-lifecycle transition.
|
|
47
|
+
export function canTransitionBorrow(from, to) {
|
|
48
|
+
return canTransition(BORROW_STATE_TRANSITIONS, from, to);
|
|
49
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { StateTransitionTable } from './state-transitions.js';
|
|
2
|
+
export declare const GIVEAWAY_STATES: readonly ["available", "claimed", "transferred", "closed"];
|
|
3
|
+
export type GiveawayState = (typeof GIVEAWAY_STATES)[number];
|
|
4
|
+
export declare const GIVEAWAY_STATE_TRANSITIONS: StateTransitionTable<GiveawayState>;
|
|
5
|
+
export declare function canTransitionGiveaway(from: GiveawayState, to: GiveawayState): boolean;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { canTransition } from './state-transitions.js';
|
|
2
|
+
// Give-away-listing lifecycle states, per REQ giveaway-lifecycle (spec
|
|
3
|
+
// display names `Available → Claimed → Transferred → Closed`, persisted as
|
|
4
|
+
// the wire values below):
|
|
5
|
+
// - 'available' — open; eligible viewers claim (claims arriving do NOT
|
|
6
|
+
// change the state — only the owner's selection does);
|
|
7
|
+
// - 'claimed' — a member of the owning Space selected exactly one
|
|
8
|
+
// claimant; other claims automatically declined;
|
|
9
|
+
// - 'transferred' — the Assetus ownership transfer to the claimant's Space
|
|
10
|
+
// succeeded (Assetus appends its own `Transferred` history event); if the
|
|
11
|
+
// transfer FAILS the Listing stays 'claimed' — staying put is not a
|
|
12
|
+
// transition;
|
|
13
|
+
// - 'closed' — terminal; immediately follows 'transferred' (or an
|
|
14
|
+
// owner-cancel — see REQ owner-cancel).
|
|
15
|
+
export const GIVEAWAY_STATES = ['available', 'claimed', 'transferred', 'closed'];
|
|
16
|
+
// The legal give-away transitions, per REQ giveaway-lifecycle +
|
|
17
|
+
// REQ owner-cancel. Any transition not listed here MUST be rejected.
|
|
18
|
+
//
|
|
19
|
+
// available → claimed owner selects exactly one claimant
|
|
20
|
+
// available → closed owner cancels (before 'transferred' — legal)
|
|
21
|
+
// claimed → transferred Assetus ownership transfer succeeded on
|
|
22
|
+
// confirmed handover (on failure the Listing
|
|
23
|
+
// remains 'claimed' — no transition)
|
|
24
|
+
// claimed → closed owner cancels; the claim is declined
|
|
25
|
+
// transferred → closed immediate, automatic
|
|
26
|
+
// closed → (terminal)
|
|
27
|
+
export const GIVEAWAY_STATE_TRANSITIONS = {
|
|
28
|
+
available: ['claimed', 'closed'],
|
|
29
|
+
claimed: ['transferred', 'closed'],
|
|
30
|
+
transferred: ['closed'],
|
|
31
|
+
closed: [],
|
|
32
|
+
};
|
|
33
|
+
// True when `from → to` is a legal give-away-lifecycle transition.
|
|
34
|
+
export function canTransitionGiveaway(from, to) {
|
|
35
|
+
return canTransition(GIVEAWAY_STATE_TRANSITIONS, from, to);
|
|
36
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './assetus-visibility.js';
|
|
2
|
+
export * from './listing-visibility.js';
|
|
3
|
+
export * from './state-transitions.js';
|
|
4
|
+
export * from './borrow-state.js';
|
|
5
|
+
export * from './giveaway-state.js';
|
|
6
|
+
export * from './listing.js';
|
|
7
|
+
export * from './transaction-log.js';
|
|
8
|
+
export * from './listing-request.js';
|
|
9
|
+
export * from './listings-endpoint.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './assetus-visibility.js';
|
|
2
|
+
export * from './listing-visibility.js';
|
|
3
|
+
export * from './state-transitions.js';
|
|
4
|
+
export * from './borrow-state.js';
|
|
5
|
+
export * from './giveaway-state.js';
|
|
6
|
+
export * from './listing.js';
|
|
7
|
+
export * from './transaction-log.js';
|
|
8
|
+
export * from './listing-request.js';
|
|
9
|
+
export * from './listings-endpoint.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const LISTING_REQUEST_STATUSES: readonly ["pending", "approved", "declined", "withdrawn"];
|
|
2
|
+
export type ListingRequestStatus = (typeof LISTING_REQUEST_STATUSES)[number];
|
|
3
|
+
export interface IListingRequestDto {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly requesterSpaceID: string;
|
|
6
|
+
readonly requesterMemberID: string;
|
|
7
|
+
readonly requesterTitle?: string;
|
|
8
|
+
readonly requesterSpaceTitle?: string;
|
|
9
|
+
readonly status: ListingRequestStatus;
|
|
10
|
+
readonly createdAt: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Status of a borrow request or give-away claim:
|
|
2
|
+
// - 'pending' — awaiting the owning Space's decision;
|
|
3
|
+
// - 'approved' — the owner approved this request (borrow) or selected this
|
|
4
|
+
// claimant (give-away); all other pending requests/claims on the Listing
|
|
5
|
+
// are automatically declined (REQ borrow-lifecycle /
|
|
6
|
+
// REQ giveaway-lifecycle);
|
|
7
|
+
// - 'declined' — declined by the owner, auto-declined because another
|
|
8
|
+
// request was approved, cancelled with the Listing (REQ owner-cancel), or
|
|
9
|
+
// auto-declined on friendship removal (REQ friendship-removal);
|
|
10
|
+
// - 'withdrawn' — the requester withdrew their own pending request
|
|
11
|
+
// (REQ borrow-request).
|
|
12
|
+
export const LISTING_REQUEST_STATUSES = [
|
|
13
|
+
'pending',
|
|
14
|
+
'approved',
|
|
15
|
+
'declined',
|
|
16
|
+
'withdrawn',
|
|
17
|
+
];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AssetusVisibility } from './assetus-visibility.js';
|
|
2
|
+
export declare const LISTING_VISIBILITIES: readonly ["private", "members", "friends"];
|
|
3
|
+
export type ListingVisibility = (typeof LISTING_VISIBILITIES)[number];
|
|
4
|
+
export declare const DEFAULT_LISTING_VISIBILITY: ListingVisibility;
|
|
5
|
+
export declare const LISTING_VISIBILITY_CEILING: Readonly<Record<AssetusVisibility, readonly ListingVisibility[]>>;
|
|
6
|
+
export declare function allowedListingVisibilities(assetVisibility: AssetusVisibility): readonly ListingVisibility[];
|
|
7
|
+
export declare function isListingVisibilityAllowed(assetVisibility: AssetusVisibility, listingVisibility: ListingVisibility): boolean;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// A Listing's own visibility, per REQ listing-visibility-ceiling (spec display
|
|
2
|
+
// names `Private` / `Members` / `Friends`, persisted as the wire values
|
|
3
|
+
// below):
|
|
4
|
+
// - 'private' — visible only to members of the owning Space;
|
|
5
|
+
// - 'members' — visible to members of the owning Space (reserved distinction
|
|
6
|
+
// from 'private' for future member-subset control; in MVP the two resolve
|
|
7
|
+
// to the same audience, and 'members' is the default);
|
|
8
|
+
// - 'friends' — additionally visible to members of befriended Spaces.
|
|
9
|
+
export const LISTING_VISIBILITIES = ['private', 'members', 'friends'];
|
|
10
|
+
// Per REQ listing-visibility-ceiling: `members` is the default listing
|
|
11
|
+
// visibility.
|
|
12
|
+
export const DEFAULT_LISTING_VISIBILITY = 'members';
|
|
13
|
+
// The asset's Assetus visibility is a CEILING on the listing's visibility,
|
|
14
|
+
// per this exact mapping from REQ listing-visibility-ceiling:
|
|
15
|
+
//
|
|
16
|
+
// | Asset visibility (Assetus) | Permitted listing visibilities |
|
|
17
|
+
// |------------------------------------------|--------------------------------|
|
|
18
|
+
// | Private | Private |
|
|
19
|
+
// | Family | Private, Members |
|
|
20
|
+
// | Specific Space | Private (MVP simplification) |
|
|
21
|
+
// | Friends, Friends of Friends, Public | Private, Members, Friends |
|
|
22
|
+
//
|
|
23
|
+
// Encoded as data so frontend and backend enforce the same source of truth.
|
|
24
|
+
// Publishing with a listing visibility not permitted here MUST be rejected
|
|
25
|
+
// with an actionable error telling the user to raise the asset's visibility
|
|
26
|
+
// in Assetus first.
|
|
27
|
+
export const LISTING_VISIBILITY_CEILING = {
|
|
28
|
+
private: ['private'],
|
|
29
|
+
family: ['private', 'members'],
|
|
30
|
+
specific_space: ['private'], // MVP simplification.
|
|
31
|
+
friends: ['private', 'members', 'friends'],
|
|
32
|
+
friends_of_friends: ['private', 'members', 'friends'],
|
|
33
|
+
public: ['private', 'members', 'friends'],
|
|
34
|
+
};
|
|
35
|
+
// The listing visibilities permitted for an asset with the given Assetus
|
|
36
|
+
// visibility. Pure lookup over `LISTING_VISIBILITY_CEILING`.
|
|
37
|
+
export function allowedListingVisibilities(assetVisibility) {
|
|
38
|
+
return LISTING_VISIBILITY_CEILING[assetVisibility];
|
|
39
|
+
}
|
|
40
|
+
// True when a listing with `listingVisibility` may be published for an asset
|
|
41
|
+
// whose Assetus visibility is `assetVisibility`.
|
|
42
|
+
export function isListingVisibilityAllowed(assetVisibility, listingVisibility) {
|
|
43
|
+
return LISTING_VISIBILITY_CEILING[assetVisibility].includes(listingVisibility);
|
|
44
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BorrowState } from './borrow-state.js';
|
|
2
|
+
import { GiveawayState } from './giveaway-state.js';
|
|
3
|
+
import { ListingVisibility } from './listing-visibility.js';
|
|
4
|
+
export declare const LISTING_TYPES: readonly ["borrow", "giveaway"];
|
|
5
|
+
export type ListingType = (typeof LISTING_TYPES)[number];
|
|
6
|
+
export type ListingState = BorrowState | GiveawayState;
|
|
7
|
+
interface IListingBase {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly spaceID: string;
|
|
10
|
+
readonly assetID: string;
|
|
11
|
+
readonly visibility: ListingVisibility;
|
|
12
|
+
}
|
|
13
|
+
export interface IBorrowListingDto extends IListingBase {
|
|
14
|
+
readonly type: 'borrow';
|
|
15
|
+
readonly state: BorrowState;
|
|
16
|
+
}
|
|
17
|
+
export interface IGiveawayListingDto extends IListingBase {
|
|
18
|
+
readonly type: 'giveaway';
|
|
19
|
+
readonly state: GiveawayState;
|
|
20
|
+
}
|
|
21
|
+
export type IListingDto = IBorrowListingDto | IGiveawayListingDto;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IListingDto } from './listing.js';
|
|
2
|
+
export type IGetListingsRequest = Record<string, never>;
|
|
3
|
+
export type ListingsGroupReason = 'member' | 'friend';
|
|
4
|
+
export interface IListingsSpaceGroup {
|
|
5
|
+
readonly spaceID: string;
|
|
6
|
+
readonly spaceTitle: string;
|
|
7
|
+
readonly reason: ListingsGroupReason;
|
|
8
|
+
readonly listings: readonly IListingDto[];
|
|
9
|
+
}
|
|
10
|
+
export interface IGetListingsResponse {
|
|
11
|
+
readonly groups: readonly IListingsSpaceGroup[];
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// True when `from → to` is a legal transition per the given table. Pure and
|
|
2
|
+
// dependency-free by design; a state never legally "transitions" to itself
|
|
3
|
+
// (staying put — e.g. a give-away remaining `claimed` after a failed Assetus
|
|
4
|
+
// transfer — is the absence of a transition, not a transition).
|
|
5
|
+
export function canTransition(table, from, to) {
|
|
6
|
+
return table[from].includes(to);
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const YARDIUS_EVENT_TYPES: readonly ["publish", "request", "withdraw", "approve", "decline", "handover", "return", "claim", "transfer", "cancel"];
|
|
2
|
+
export type YardiusEventType = (typeof YARDIUS_EVENT_TYPES)[number];
|
|
3
|
+
export interface ITransactionLogEntry {
|
|
4
|
+
readonly event: YardiusEventType;
|
|
5
|
+
readonly at: string;
|
|
6
|
+
readonly actingMemberSpaceID: string;
|
|
7
|
+
readonly actingMemberID: string;
|
|
8
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// The exact set of lifecycle event types recorded in a Listing's per-listing
|
|
2
|
+
// transaction log, per REQ transaction-log.
|
|
3
|
+
export const YARDIUS_EVENT_TYPES = [
|
|
4
|
+
'publish',
|
|
5
|
+
'request',
|
|
6
|
+
'withdraw',
|
|
7
|
+
'approve',
|
|
8
|
+
'decline',
|
|
9
|
+
'handover',
|
|
10
|
+
'return',
|
|
11
|
+
'claim',
|
|
12
|
+
'transfer',
|
|
13
|
+
'cancel',
|
|
14
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sneat/extension-yardius-contract",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Frozen cross-repo contract surface (shared DTOs, consts, briefs) for the yardius Sneat extension",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/sneat-co/ext-yardius.git"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@nx/js": "22.7.5",
|
|
27
|
+
"nx": "22.7.5",
|
|
28
|
+
"typescript": "~5.9.3",
|
|
29
|
+
"vite": "^7.2.7",
|
|
30
|
+
"vitest": "4.0.9"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc -p tsconfig.build.json",
|
|
34
|
+
"typecheck": "tsc --noEmit",
|
|
35
|
+
"test": "vitest run"
|
|
36
|
+
}
|
|
37
|
+
}
|