Skip to content

Commit

Permalink
Zoe .d.ts libcheck (#9374)
Browse files Browse the repository at this point in the history
refs: #9364

## Description

Follow-up to #9364, also doing the `skipLibCheck: false` for Zoe package
and fixing up most of the issues. (Documenting the deferred).


### Security Considerations

<!-- Does this change introduce new assumptions or dependencies that, if
violated, could introduce security vulnerabilities? How does this PR
change the boundaries between mutually-suspicious components? What new
authorities are introduced by this change, perhaps by new API calls?
-->

### Scaling Considerations

<!-- Does this change require or encourage significant increase in
consumption of CPU cycles, RAM, on-chain storage, message exchanges, or
other scarce resources? If so, can that be prevented or mitigated? -->

### Documentation Considerations

<!-- Give our docs folks some hints about what needs to be described to
downstream users.

Backwards compatibility: what happens to existing data or deployments
when this code is shipped? Do we need to instruct users to do something
to upgrade their saved data? If there is no upgrade path possible, how
bad will that be for users?

-->

### Testing Considerations

<!-- Every PR should of course come with tests of its own functionality.
What additional tests are still needed beyond those unit tests? How does
this affect CI, other test automation, or the testnet?
-->

### Upgrade Considerations

just types and tests. will not affect production but small impact on
release process (cherry picking)
  • Loading branch information
mergify[bot] authored May 16, 2024
2 parents 0f94e34 + 72b3b76 commit 303a9f2
Show file tree
Hide file tree
Showing 21 changed files with 147 additions and 88 deletions.
2 changes: 1 addition & 1 deletion packages/governance/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,6 @@
"access": "public"
},
"typeCoverage": {
"atLeast": 89.31
"atLeast": 89.32
}
}
2 changes: 1 addition & 1 deletion packages/inter-protocol/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,6 @@
"access": "public"
},
"typeCoverage": {
"atLeast": 95.86
"atLeast": 95.87
}
}
2 changes: 1 addition & 1 deletion packages/vats/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@
"workerThreads": false
},
"typeCoverage": {
"atLeast": 91.25
"atLeast": 91.26
}
}
47 changes: 30 additions & 17 deletions packages/vats/src/core/types-ambient.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,36 @@ type WellKnownName = {
uiConfig: 'VaultFactory';
};

type ContractInstallationPromises<StartFns> = {
type ContractInstallationPromises<
StartFns extends Record<WellKnownNames['installation'], ContractStartFn>,
> = {
[Property in keyof StartFns]: Promise<Installation<StartFns[Property]>>;
};

type ContractInstancePromises<
StartFns extends Record<WellKnownNames['instance'], ContractStartFn>,
> = {
[Property in keyof StartFns]: Promise<
import('@agoric/zoe/src/zoeService/utils.js').Instance<StartFns[Property]>
>;
};

type WellKnownContracts = {
auctioneer: typeof import('@agoric/inter-protocol/src/auction/auctioneer.js').start;
centralSupply: typeof import('@agoric/vats/src/centralSupply.js').start;
committee: typeof import('@agoric/governance/src/committee.js').start;
contractGovernor: typeof import('@agoric/governance/src/contractGovernor.js').start;
econCommitteeCharter: typeof import('@agoric/inter-protocol/src/econCommitteeCharter.js').start;
feeDistributor: typeof import('@agoric/inter-protocol/src/feeDistributor.js').start;
mintHolder: typeof import('@agoric/vats/src/mintHolder.js').start;
psm: typeof import('@agoric/inter-protocol/src/psm/psm.js').start;
provisionPool: typeof import('@agoric/inter-protocol/src/provisionPool.js').start;
reserve: typeof import('@agoric/inter-protocol/src/reserve/assetReserve.js').start;
VaultFactory: typeof import('@agoric/inter-protocol/src/vaultFactory/vaultFactory.js').start;
// no typeof because walletFactory is exporting `start` as a type
walletFactory: import('@agoric/smart-wallet/src/walletFactory.js').start;
};

type WellKnownSpaces = {
issuer: {
produce: Record<WellKnownName['issuer'], Producer<Issuer>>;
Expand Down Expand Up @@ -233,25 +259,12 @@ type WellKnownSpaces = {
WellKnownName['installation'],
Promise<Installation<unknown>>
> &
ContractInstallationPromises<{
auctioneer: typeof import('@agoric/inter-protocol/src/auction/auctioneer.js').start;
centralSupply: typeof import('@agoric/vats/src/centralSupply.js').start;
committee: typeof import('@agoric/governance/src/committee.js').start;
contractGovernor: typeof import('@agoric/governance/src/contractGovernor.js').start;
econCommitteeCharter: typeof import('@agoric/inter-protocol/src/econCommitteeCharter.js').start;
feeDistributor: typeof import('@agoric/inter-protocol/src/feeDistributor.js').start;
mintHolder: typeof import('@agoric/vats/src/mintHolder.js').start;
psm: typeof import('@agoric/inter-protocol/src/psm/psm.js').start;
provisionPool: typeof import('@agoric/inter-protocol/src/provisionPool.js').start;
reserve: typeof import('@agoric/inter-protocol/src/reserve/assetReserve.js').start;
VaultFactory: typeof import('@agoric/inter-protocol/src/vaultFactory/vaultFactory.js').start;
// no typeof because walletFactory is exporting `start` as a type
walletFactory: import('@agoric/smart-wallet/src/walletFactory.js').start;
}>;
ContractInstallationPromises<WellKnownContracts>;
};
instance: {
produce: Record<WellKnownName['instance'], Producer<Instance>>;
consume: Record<WellKnownName['instance'], Promise<Instance>>;
consume: Record<WellKnownName['instance'], Promise<Instance>> &
ContractInstancePromises<WellKnownContracts>;
};
uiConfig: {
produce: Record<WellKnownName['uiConfig'], Producer<Record<string, any>>>;
Expand Down
30 changes: 30 additions & 0 deletions packages/vats/test/types-ambient.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* eslint-disable @jessie.js/safe-await-separator */
/* eslint @typescript-eslint/no-floating-promises: "warn" */
/**
* @file uses .ts syntax to be able to declare types (e.g. of kit.creatorFacet
* as {}) because "there is no JavaScript syntax for passing a a type
* argument"
* https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html
*/

/// <reference path="../src/core/types-ambient.d.ts" />

import type { start as assetReserveStart } from '@agoric/inter-protocol/src/reserve/assetReserve.js';
import { expectNotType, expectType } from 'tsd';

import type { Instance } from '@agoric/zoe/src/zoeService/utils.js';

const mock = null as any;

const spaces: WellKnownSpaces = mock;

expectType<Instance<typeof assetReserveStart>>(
await spaces.instance.consume.reserve,
);
expectType<Instance<typeof assetReserveStart>>(
// @ts-expect-error to check against `any` Instance
await spaces.instance.consume.provisionPool,
);
expectNotType<Instance<typeof assetReserveStart>>(
await spaces.instance.consume.provisionPool,
);
9 changes: 5 additions & 4 deletions packages/vats/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
},
"include": [
"*.js",
"scripts/**/*.js",
"scripts",
// XXX we need both globs or tsc will ignore the .d.ts twin
"src/**/*.js",
"src/**/*.d.ts",
"test/**/*.js",
"tools/**/*.js",
"src/**/*.ts",
"test",
"tools",
],
}
2 changes: 1 addition & 1 deletion packages/zoe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,6 @@
"access": "public"
},
"typeCoverage": {
"atLeast": 84.91
"atLeast": 84.92
}
}
20 changes: 12 additions & 8 deletions packages/zoe/src/contractFacet/types-ambient.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
type CopyRecord<T> = import('@endo/pass-style').CopyRecord<T>;
type IssuerOptionsRecord = import('@agoric/ertp').IssuerOptionsRecord;
/// <reference types="@agoric/ertp/exported" />
/// <reference types="@endo/pass-style" />
/// <reference path="../zoeService/utils.d.ts" />

/**
* Any passable non-thenable. Often an explanatory string.
*/
type Completion = any;
type Completion = import('@endo/pass-style').Passable;
type ZCFMakeEmptySeatKit = (exit?: ExitRule | undefined) => ZcfSeatKit;

type InvitationAmount = Amount<'set', InvitationDetails>;
Expand Down Expand Up @@ -62,7 +64,7 @@ type ZCF<CT extends unknown = Record<string, unknown>> = {
proposalShape?: Pattern,
) => Promise<Invitation<R, A>>;
shutdown: (completion: Completion) => void;
shutdownWithFailure: ShutdownWithFailure;
shutdownWithFailure: import('@agoric/swingset-vat').ShutdownWithFailure;
getZoeService: () => ERef<ZoeService>;
getInvitationIssuer: () => Issuer<'set'>;
getTerms: () => StandardTerms & CT;
Expand All @@ -73,7 +75,7 @@ type ZCF<CT extends unknown = Record<string, unknown>> = {
keyword: Keyword,
assetKind?: K_2 | undefined,
displayInfo?: AdditionalDisplayInfo,
options?: IssuerOptionsRecord,
options?: import('@agoric/ertp').IssuerOptionsRecord,
) => Promise<ZCFMint<K_2>>;
registerFeeMint: ZCFRegisterFeeMint;
makeEmptySeatKit: ZCFMakeEmptySeatKit;
Expand Down Expand Up @@ -216,8 +218,8 @@ type OfferHandler<OR extends unknown = unknown, OA = never> =
handle: HandleOffer<OR, OA>;
};
type ContractMeta = {
customTermsShape?: CopyRecord<any> | undefined;
privateArgsShape?: CopyRecord<any> | undefined;
customTermsShape?: import('@endo/pass-style').CopyRecord<any> | undefined;
privateArgsShape?: import('@endo/pass-style').CopyRecord<any> | undefined;
upgradability?: 'none' | 'canBeUpgraded' | 'canUpgrade' | undefined;
};
/**
Expand All @@ -238,8 +240,10 @@ type ContractStartFn<
type ContractStartFnResult<PF, CF> = {
publicFacet?: PF;
creatorFacet?: CF;
creatorInvitation?: Promise<Invitation<R, A>> | undefined;
creatorInvitation?: Promise<Invitation<any, any>> | undefined;
};

// XXX redef, losing documentation
type ContractOf<S> = import('../zoeService/utils').ContractOf<S>;
type AdminFacet = import('../zoeService/utils').AdminFacet<any>;

Expand Down
4 changes: 4 additions & 0 deletions packages/zoe/src/contracts/oracle.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { AmountMath } from '@agoric/ertp';
import { E } from '@endo/eventual-send';
import { atomicTransfer } from '../contractSupport/index.js';

/**
* @import {ContractOf} from '../zoeService/utils.js';
*/

/**
* This contract provides oracle queries for a fee or for free.
*
Expand Down
1 change: 1 addition & 0 deletions packages/zoe/src/contracts/priceAggregator.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {

/**
* @import {LegacyMap} from '@agoric/store'
* @import {ContractOf} from '../zoeService/utils.js';
* @import {PriceDescription, PriceQuote, PriceQuoteValue, PriceQuery,} from '@agoric/zoe/tools/types.js';
*/
/** @typedef {bigint | number | string} ParsableNumber */
Expand Down
3 changes: 2 additions & 1 deletion packages/zoe/src/internal-types.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// @jessie-check
/// <reference types="@agoric/ertp/exported" />

/**
* @typedef {object} SeatData
Expand Down Expand Up @@ -163,7 +164,7 @@
* @param {Keyword} keyword
* @param {AssetKind} [assetKind]
* @param {AdditionalDisplayInfo} [displayInfo]
* @param {IssuerOptionsRecord} [options]
* @param {import('@agoric/ertp').IssuerOptionsRecord} [options]
* @returns {ZoeMint}
*/

Expand Down
2 changes: 1 addition & 1 deletion packages/zoe/src/zoeService/startInstance.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const makeStartInstance = (
adminNode: M.remotable('adminNode'),
});

/** @type {import('@agoric/swingset-liveslots').PromiseWatcher<unknown, [InstanceAdmin, Handle<'adminNode'>]>} */
/** @type {import('@agoric/swingset-liveslots').PromiseWatcher<Completion, [InstanceAdmin, Handle<'adminNode'>]>} */
const watcher = prepareExo(
zoeBaggage,
'InstanceCompletionWatcher',
Expand Down
42 changes: 16 additions & 26 deletions packages/zoe/src/zoeService/utils.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
// Ambient types
import '../types-ambient.js';
import '../contractFacet/types-ambient.js';

import type { Issuer } from '@agoric/ertp/exported.js';
import type { TagContainer } from '@agoric/internal/src/tagged.js';
import type { Callable } from '@agoric/internal/src/utils.js';
import type { Baggage } from '@agoric/swingset-liveslots';
import type { VatUpgradeResults } from '@agoric/swingset-vat';
import type { RemotableObject } from '@endo/marshal';

// XXX https://github.com/Agoric/agoric-sdk/issues/4565
type SourceBundle = Record<string, any>;

type ContractFacet<T extends {} = {}> = {
readonly [P in keyof T]: T[P] extends Callable ? T[P] : never;
};

/**
* Installation of a contract, typed by its start function.
*/
Expand Down Expand Up @@ -48,41 +47,30 @@ export type AdminFacet<SF extends ContractStartFunction> = RemotableObject & {
: (newPrivateArgs: Parameters<SF>[1]) => Promise<VatUpgradeResults>;
};

type StartParams<SF> = SF extends ContractStartFunction
export type StartParams<SF> = SF extends ContractStartFunction
? Parameters<SF>[1] extends undefined
? {
terms: ReturnType<Parameters<SF>[0]['getTerms']>;
terms: ReturnType<ZcfOf<SF>['getTerms']>;
}
: {
terms: ReturnType<Parameters<SF>[0]['getTerms']>;
terms: ReturnType<ZcfOf<SF>['getTerms']>;
privateArgs: Parameters<SF>[1];
}
: never;

type StartResult<S> = S extends (...args: any) => Promise<infer U>
? U
: ReturnType<S>;
type StartResult<S extends (...args: any) => any> = Awaited<ReturnType<S>>;
type ZcfOf<SF extends ContractStartFunction> = Parameters<SF>[0] extends ZCF
? Parameters<SF>[0]
: ZCF<any>;

/**
* Convenience record for contract start function, merging its result with params.
*/
export type ContractOf<S> = StartParams<S> & StartResult<S>;

type StartContractInstance<C> = (
installation: Installation<C>,
issuerKeywordRecord?: Record<string, Issuer<any>>,
terms?: object,
privateArgs?: object,
) => Promise<{
creatorFacet: C['creatorFacet'];
publicFacet: C['publicFacet'];
instance: Instance;
creatorInvitation: C['creatorInvitation'];
adminFacet: AdminFacet<any>;
}>;
export type ContractOf<S extends (...args: any) => any> = StartParams<S> &
StartResult<S>;

/** The result of `startInstance` */
export type StartedInstanceKit<SF> = {
export type StartedInstanceKit<SF extends ContractStartFunction> = {
instance: Instance<SF>;
adminFacet: AdminFacet<SF>;
// theses are empty by default. the return type will override
Expand Down Expand Up @@ -110,6 +98,7 @@ export type StartedInstanceKit<SF> = {
* the creator facet, public facet, and creator invitation as defined
* by the contract.
*/
// XXX SF should extend ContractStartFunction but doing that triggers a bunch of tech debt type errors
export type StartInstance = <SF>(
installation: Installation<SF> | PromiseLike<Installation<SF>>,
issuerKeywordRecord?: Record<Keyword, Issuer<any>>,
Expand All @@ -119,6 +108,7 @@ export type StartInstance = <SF>(
label?: string,
) => Promise<StartedInstanceKit<SF>>;

// XXX SF should extend ContractStartFunction but doing that triggers a bunch of tech debt type errors
export type GetPublicFacet = <SF>(
instance: Instance<SF> | PromiseLike<Instance<SF>>,
) => Promise<StartResult<SF>['publicFacet']>;
Expand Down
2 changes: 1 addition & 1 deletion packages/zoe/src/zoeService/utils.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { StartedInstanceKit } from './utils';
const someContractStartFn = (
zcf: ZCF,
privateArgs: { someNumber: number; someString: string },
) => {};
) => ({});

type PsmInstanceKit = StartedInstanceKit<typeof someContractStartFn>;

Expand Down
Loading

0 comments on commit 303a9f2

Please sign in to comment.