@agoric/deploy-script-support 0.10.4-dev-99fc025.0 → 0.10.4-dev-2c609b8.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/package.json +11 -11
- package/src/extract-proposal.js +188 -143
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/deploy-script-support",
|
|
3
|
-
"version": "0.10.4-dev-
|
|
3
|
+
"version": "0.10.4-dev-2c609b8.0+2c609b8",
|
|
4
4
|
"description": "Helpers and other support for writing deploy scripts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/helpers.js",
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@agoric/assert": "0.6.1-dev-
|
|
38
|
-
"@agoric/ertp": "0.16.3-dev-
|
|
39
|
-
"@agoric/import-manager": "0.3.12-dev-
|
|
40
|
-
"@agoric/internal": "0.3.3-dev-
|
|
41
|
-
"@agoric/notifier": "0.6.3-dev-
|
|
42
|
-
"@agoric/store": "0.9.3-dev-
|
|
43
|
-
"@agoric/time": "0.3.3-dev-
|
|
44
|
-
"@agoric/zoe": "0.26.3-dev-
|
|
37
|
+
"@agoric/assert": "0.6.1-dev-2c609b8.0+2c609b8",
|
|
38
|
+
"@agoric/ertp": "0.16.3-dev-2c609b8.0+2c609b8",
|
|
39
|
+
"@agoric/import-manager": "0.3.12-dev-2c609b8.0+2c609b8",
|
|
40
|
+
"@agoric/internal": "0.3.3-dev-2c609b8.0+2c609b8",
|
|
41
|
+
"@agoric/notifier": "0.6.3-dev-2c609b8.0+2c609b8",
|
|
42
|
+
"@agoric/store": "0.9.3-dev-2c609b8.0+2c609b8",
|
|
43
|
+
"@agoric/time": "0.3.3-dev-2c609b8.0+2c609b8",
|
|
44
|
+
"@agoric/zoe": "0.26.3-dev-2c609b8.0+2c609b8",
|
|
45
45
|
"@endo/base64": "^1.0.1",
|
|
46
46
|
"@endo/bundle-source": "^3.0.2",
|
|
47
47
|
"@endo/far": "^1.0.2",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@endo/zip": "^1.0.1"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@agoric/vats": "0.15.2-dev-
|
|
54
|
+
"@agoric/vats": "0.15.2-dev-2c609b8.0+2c609b8",
|
|
55
55
|
"@endo/init": "^1.0.2",
|
|
56
56
|
"ava": "^5.3.0",
|
|
57
57
|
"import-meta-resolve": "^2.2.1"
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"typeCoverage": {
|
|
76
76
|
"atLeast": 80.06
|
|
77
77
|
},
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "2c609b84ddd07536404dedf45b118b1625ce81a0"
|
|
79
79
|
}
|
package/src/extract-proposal.js
CHANGED
|
@@ -11,13 +11,38 @@ import {
|
|
|
11
11
|
} from './coreProposalBehavior.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* @typedef {string | {
|
|
14
|
+
* @typedef {string | {module: string, entrypoint?: string, args?: Array<unknown>}} ConfigProposal
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {ConfigProposal[] | {steps: ConfigProposal[][]}} CoreProposals
|
|
15
19
|
*/
|
|
16
20
|
|
|
17
21
|
const { Fail } = assert;
|
|
18
22
|
|
|
19
23
|
const req = createRequire(import.meta.url);
|
|
20
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @param {...(CoreProposals | undefined | null)} args
|
|
27
|
+
* @returns {CoreProposals}
|
|
28
|
+
*/
|
|
29
|
+
export const mergeCoreProposals = (...args) => {
|
|
30
|
+
/** @type {ConfigProposal[][]} */
|
|
31
|
+
const steps = [];
|
|
32
|
+
for (const coreProposal of args) {
|
|
33
|
+
if (!coreProposal) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if ('steps' in coreProposal) {
|
|
37
|
+
steps.push(...coreProposal.steps);
|
|
38
|
+
} else {
|
|
39
|
+
steps.push(coreProposal);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return harden({ steps });
|
|
43
|
+
};
|
|
44
|
+
harden(mergeCoreProposals);
|
|
45
|
+
|
|
21
46
|
/**
|
|
22
47
|
* @param {(ModuleSpecifier | FilePath)[]} paths
|
|
23
48
|
* @typedef {string} ModuleSpecifier
|
|
@@ -43,12 +68,12 @@ const findModule = (initDir, srcSpec) =>
|
|
|
43
68
|
/**
|
|
44
69
|
* @param {{ bundleID?: string, bundleName?: string }} handle - mutated then hardened
|
|
45
70
|
* @param {string} sourceSpec - the specifier of a module to load
|
|
46
|
-
* @param {
|
|
71
|
+
* @param {string} key - the key of the proposal
|
|
47
72
|
* @param {string} piece - the piece of the proposal
|
|
48
73
|
* @returns {Promise<[string, any]>}
|
|
49
74
|
*/
|
|
50
|
-
const namedHandleToBundleSpec = async (handle, sourceSpec,
|
|
51
|
-
handle.bundleName = `coreProposal${
|
|
75
|
+
const namedHandleToBundleSpec = async (handle, sourceSpec, key, piece) => {
|
|
76
|
+
handle.bundleName = `coreProposal${String(key)}_${piece}`;
|
|
52
77
|
harden(handle);
|
|
53
78
|
return harden([handle.bundleName, { sourceSpec }]);
|
|
54
79
|
};
|
|
@@ -64,12 +89,12 @@ const namedHandleToBundleSpec = async (handle, sourceSpec, sequence, piece) => {
|
|
|
64
89
|
* but for sim-chain and such, they can be declared statically in
|
|
65
90
|
* the chain configuration, in which case they are run at bootstrap.
|
|
66
91
|
*
|
|
67
|
-
* @param {
|
|
92
|
+
* @param {CoreProposals} coreProposals - governance
|
|
68
93
|
* proposals to run at chain bootstrap for scenarios such as sim-chain.
|
|
69
94
|
* @param {FilePath} [dirname]
|
|
70
95
|
* @param {object} [opts]
|
|
71
96
|
* @param {typeof makeEnactCoreProposalsFromBundleRef} [opts.makeEnactCoreProposals]
|
|
72
|
-
* @param {(
|
|
97
|
+
* @param {(key: PropertyKey) => PropertyKey} [opts.getSequenceForProposal]
|
|
73
98
|
* @param {typeof namedHandleToBundleSpec} [opts.handleToBundleSpec]
|
|
74
99
|
*/
|
|
75
100
|
export const extractCoreProposalBundles = async (
|
|
@@ -79,7 +104,7 @@ export const extractCoreProposalBundles = async (
|
|
|
79
104
|
) => {
|
|
80
105
|
const {
|
|
81
106
|
makeEnactCoreProposals = makeEnactCoreProposalsFromBundleRef,
|
|
82
|
-
getSequenceForProposal =
|
|
107
|
+
getSequenceForProposal = key => key,
|
|
83
108
|
handleToBundleSpec = namedHandleToBundleSpec,
|
|
84
109
|
} = opts || {};
|
|
85
110
|
|
|
@@ -91,159 +116,177 @@ export const extractCoreProposalBundles = async (
|
|
|
91
116
|
/** @type {Map<{ bundleID?: string, bundleName?: string }, { source: string, bundle?: string }>} */
|
|
92
117
|
const bundleHandleToAbsolutePaths = new Map();
|
|
93
118
|
|
|
119
|
+
const proposalSteps =
|
|
120
|
+
'steps' in coreProposals ? coreProposals.steps : [coreProposals];
|
|
94
121
|
const bundleToSource = new Map();
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
122
|
+
const extractedSteps = await Promise.all(
|
|
123
|
+
proposalSteps.map((proposalStep, i) =>
|
|
124
|
+
Promise.all(
|
|
125
|
+
proposalStep.map(async (coreProposal, j) => {
|
|
126
|
+
const key = `${i}.${j}`;
|
|
127
|
+
// console.debug(`Parsing core proposal:`, coreProposal);
|
|
98
128
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
} else {
|
|
110
|
-
({ module, entrypoint, args = [] } = coreProposal);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
typeof module === 'string' ||
|
|
114
|
-
Fail`coreProposal module ${module} must be string`;
|
|
115
|
-
typeof entrypoint === 'string' ||
|
|
116
|
-
Fail`coreProposal entrypoint ${entrypoint} must be string`;
|
|
117
|
-
Array.isArray(args) || Fail`coreProposal args ${args} must be array`;
|
|
118
|
-
|
|
119
|
-
const thisProposalBundleHandles = new Set();
|
|
120
|
-
assert(getSequenceForProposal);
|
|
121
|
-
const thisProposalSequence = getSequenceForProposal(i);
|
|
122
|
-
const initPath = findModule(dirname, module);
|
|
123
|
-
const initDir = path.dirname(initPath);
|
|
124
|
-
/** @type {Record<string, import('./externalTypes.js').ProposalBuilder>} */
|
|
125
|
-
const ns = await import(initPath);
|
|
126
|
-
const install = (srcSpec, bundlePath) => {
|
|
127
|
-
const absoluteSrc = findModule(initDir, srcSpec);
|
|
128
|
-
const bundleHandle = {};
|
|
129
|
-
const absolutePaths = { source: absoluteSrc };
|
|
130
|
-
if (bundlePath) {
|
|
131
|
-
const absoluteBundle = pathResolve(initDir, bundlePath);
|
|
132
|
-
absolutePaths.bundle = absoluteBundle;
|
|
133
|
-
const oldSource = bundleToSource.get(absoluteBundle);
|
|
134
|
-
if (oldSource) {
|
|
135
|
-
oldSource === absoluteSrc ||
|
|
136
|
-
Fail`${bundlePath} already installed from ${oldSource}, now ${absoluteSrc}`;
|
|
129
|
+
/** @type {string} */
|
|
130
|
+
let entrypoint;
|
|
131
|
+
/** @type {unknown[]} */
|
|
132
|
+
let args;
|
|
133
|
+
/** @type {string} */
|
|
134
|
+
let module;
|
|
135
|
+
if (typeof coreProposal === 'string') {
|
|
136
|
+
module = coreProposal;
|
|
137
|
+
entrypoint = 'defaultProposalBuilder';
|
|
138
|
+
args = [];
|
|
137
139
|
} else {
|
|
138
|
-
|
|
140
|
+
({
|
|
141
|
+
module,
|
|
142
|
+
entrypoint = 'defaultProposalBuilder',
|
|
143
|
+
args = [],
|
|
144
|
+
} = coreProposal);
|
|
139
145
|
}
|
|
140
|
-
}
|
|
141
|
-
// Don't harden the bundleHandle since we need to set the bundleName on
|
|
142
|
-
// its unique identity later.
|
|
143
|
-
thisProposalBundleHandles.add(bundleHandle);
|
|
144
|
-
bundleHandleToAbsolutePaths.set(bundleHandle, harden(absolutePaths));
|
|
145
|
-
return bundleHandle;
|
|
146
|
-
};
|
|
147
|
-
/** @type {import('./externalTypes.js').PublishBundleRef} */
|
|
148
|
-
const publishRef = async handleP => {
|
|
149
|
-
const handle = await handleP;
|
|
150
|
-
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error -- https://github.com/Agoric/agoric-sdk/issues/4620 */
|
|
151
|
-
// @ts-ignore xxx types
|
|
152
|
-
bundleHandleToAbsolutePaths.has(handle) ||
|
|
153
|
-
Fail`${handle} not in installed bundles`;
|
|
154
|
-
return handle;
|
|
155
|
-
};
|
|
156
|
-
const proposal = await ns[entrypoint](
|
|
157
|
-
{
|
|
158
|
-
publishRef,
|
|
159
|
-
// @ts-expect-error not statically verified to return a full obj
|
|
160
|
-
install,
|
|
161
|
-
},
|
|
162
|
-
...args,
|
|
163
|
-
);
|
|
164
146
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
147
|
+
typeof module === 'string' ||
|
|
148
|
+
Fail`coreProposal module ${module} must be string`;
|
|
149
|
+
typeof entrypoint === 'string' ||
|
|
150
|
+
Fail`coreProposal entrypoint ${entrypoint} must be string`;
|
|
151
|
+
Array.isArray(args) || Fail`coreProposal args ${args} must be array`;
|
|
152
|
+
|
|
153
|
+
const thisProposalBundleHandles = new Set();
|
|
154
|
+
assert(getSequenceForProposal);
|
|
155
|
+
const thisProposalSequence = getSequenceForProposal(key);
|
|
156
|
+
const initPath = findModule(dirname, module);
|
|
157
|
+
const initDir = path.dirname(initPath);
|
|
158
|
+
/** @type {Record<string, import('./externalTypes.js').ProposalBuilder>} */
|
|
159
|
+
const ns = await import(initPath);
|
|
160
|
+
const install = (srcSpec, bundlePath) => {
|
|
161
|
+
const absoluteSrc = findModule(initDir, srcSpec);
|
|
162
|
+
const bundleHandle = {};
|
|
163
|
+
const absolutePaths = { source: absoluteSrc };
|
|
164
|
+
if (bundlePath) {
|
|
165
|
+
const absoluteBundle = pathResolve(initDir, bundlePath);
|
|
166
|
+
absolutePaths.bundle = absoluteBundle;
|
|
167
|
+
const oldSource = bundleToSource.get(absoluteBundle);
|
|
168
|
+
if (oldSource) {
|
|
169
|
+
oldSource === absoluteSrc ||
|
|
170
|
+
Fail`${bundlePath} already installed from ${oldSource}, now ${absoluteSrc}`;
|
|
171
|
+
} else {
|
|
172
|
+
bundleToSource.set(absoluteBundle, absoluteSrc);
|
|
173
|
+
}
|
|
175
174
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
absolutePaths.source,
|
|
183
|
-
thisProposalSequence,
|
|
184
|
-
String(j),
|
|
175
|
+
// Don't harden the bundleHandle since we need to set the bundleName on
|
|
176
|
+
// its unique identity later.
|
|
177
|
+
thisProposalBundleHandles.add(bundleHandle);
|
|
178
|
+
bundleHandleToAbsolutePaths.set(
|
|
179
|
+
bundleHandle,
|
|
180
|
+
harden(absolutePaths),
|
|
185
181
|
);
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
182
|
+
return bundleHandle;
|
|
183
|
+
};
|
|
184
|
+
/** @type {import('./externalTypes.js').PublishBundleRef} */
|
|
185
|
+
const publishRef = async handleP => {
|
|
186
|
+
const handle = await handleP;
|
|
187
|
+
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error -- https://github.com/Agoric/agoric-sdk/issues/4620 */
|
|
188
|
+
// @ts-ignore xxx types
|
|
189
|
+
bundleHandleToAbsolutePaths.has(handle) ||
|
|
190
|
+
Fail`${handle} not in installed bundles`;
|
|
191
|
+
return handle;
|
|
192
|
+
};
|
|
193
|
+
const proposal = await ns[entrypoint](
|
|
194
|
+
{
|
|
195
|
+
publishRef,
|
|
196
|
+
// @ts-expect-error not statically verified to return a full obj
|
|
197
|
+
install,
|
|
198
|
+
},
|
|
199
|
+
...args,
|
|
200
|
+
);
|
|
190
201
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
202
|
+
// Add the proposal bundle handles in sorted order.
|
|
203
|
+
const bundleSpecEntries = await Promise.all(
|
|
204
|
+
[...thisProposalBundleHandles.keys()]
|
|
205
|
+
.map(handle => [handle, bundleHandleToAbsolutePaths.get(handle)])
|
|
206
|
+
.sort(([_hnda, { source: a }], [_hndb, { source: b }]) => {
|
|
207
|
+
if (a < b) {
|
|
208
|
+
return -1;
|
|
209
|
+
}
|
|
210
|
+
if (a > b) {
|
|
211
|
+
return 1;
|
|
212
|
+
}
|
|
213
|
+
return 0;
|
|
214
|
+
})
|
|
215
|
+
.map(async ([handle, absolutePaths], k) => {
|
|
216
|
+
// Transform the bundle handle identity into a bundleName reference.
|
|
217
|
+
const specEntry = await handleToBundleSpec(
|
|
218
|
+
handle,
|
|
219
|
+
absolutePaths.source,
|
|
220
|
+
thisProposalSequence,
|
|
221
|
+
String(k),
|
|
222
|
+
);
|
|
223
|
+
harden(handle);
|
|
224
|
+
return specEntry;
|
|
225
|
+
}),
|
|
226
|
+
);
|
|
196
227
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const { manifest: customManifest } = await proposalNS[manifestGetterName](
|
|
203
|
-
harden({ restoreRef: () => null }),
|
|
204
|
-
...manifestGetterArgs,
|
|
205
|
-
);
|
|
228
|
+
// Now that we've assigned all the bundleNames and hardened the
|
|
229
|
+
// handles, we can extract the behavior bundle.
|
|
230
|
+
const { sourceSpec, getManifestCall } = await deeplyFulfilledObject(
|
|
231
|
+
harden(proposal),
|
|
232
|
+
);
|
|
206
233
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
234
|
+
const proposalSource = pathResolve(initDir, sourceSpec);
|
|
235
|
+
const proposalNS = await import(proposalSource);
|
|
236
|
+
const [manifestGetterName, ...manifestGetterArgs] = getManifestCall;
|
|
237
|
+
manifestGetterName in proposalNS ||
|
|
238
|
+
Fail`proposal ${proposalSource} missing export ${manifestGetterName}`;
|
|
239
|
+
const { manifest: customManifest } = await proposalNS[
|
|
240
|
+
manifestGetterName
|
|
241
|
+
](harden({ restoreRef: () => null }), ...manifestGetterArgs);
|
|
215
242
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
243
|
+
const behaviorBundleHandle = {};
|
|
244
|
+
const specEntry = await handleToBundleSpec(
|
|
245
|
+
behaviorBundleHandle,
|
|
246
|
+
proposalSource,
|
|
247
|
+
thisProposalSequence,
|
|
248
|
+
'proposalNS',
|
|
249
|
+
);
|
|
250
|
+
bundleSpecEntries.unshift(specEntry);
|
|
251
|
+
|
|
252
|
+
bundleHandleToAbsolutePaths.set(
|
|
253
|
+
behaviorBundleHandle,
|
|
254
|
+
harden({
|
|
255
|
+
source: proposalSource,
|
|
256
|
+
}),
|
|
257
|
+
);
|
|
222
258
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
259
|
+
return /** @type {const} */ ([
|
|
260
|
+
key,
|
|
261
|
+
{
|
|
262
|
+
ref: behaviorBundleHandle,
|
|
263
|
+
call: getManifestCall,
|
|
264
|
+
customManifest,
|
|
265
|
+
bundleSpecs: bundleSpecEntries,
|
|
266
|
+
},
|
|
267
|
+
]);
|
|
268
|
+
}),
|
|
269
|
+
),
|
|
270
|
+
),
|
|
230
271
|
);
|
|
231
272
|
|
|
232
273
|
// Extract all the bundle specs in already-sorted order.
|
|
233
274
|
const bundles = Object.fromEntries(
|
|
234
|
-
|
|
275
|
+
extractedSteps.flatMap(step =>
|
|
276
|
+
step.flatMap(([_key, { bundleSpecs }]) => bundleSpecs),
|
|
277
|
+
),
|
|
235
278
|
);
|
|
236
279
|
harden(bundles);
|
|
237
280
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
281
|
+
const codeSteps = extractedSteps.map(extractedStep => {
|
|
282
|
+
// Extract the manifest references and calls.
|
|
283
|
+
const metadataRecords = extractedStep.map(([_key, extractedSpec]) => {
|
|
284
|
+
const { ref, call, customManifest } = extractedSpec;
|
|
285
|
+
return { ref, call, customManifest };
|
|
286
|
+
});
|
|
287
|
+
harden(metadataRecords);
|
|
245
288
|
|
|
246
|
-
|
|
289
|
+
const code = `\
|
|
247
290
|
// This is generated by @agoric/deploy-script-support/src/extract-proposal.js - DO NOT EDIT
|
|
248
291
|
/* eslint-disable */
|
|
249
292
|
|
|
@@ -260,11 +303,13 @@ const enactCoreProposals = ((
|
|
|
260
303
|
) => makeEnactCoreProposals({ metadataRecords, E }))();
|
|
261
304
|
enactCoreProposals;
|
|
262
305
|
`;
|
|
306
|
+
return defangAndTrim(code);
|
|
307
|
+
});
|
|
263
308
|
|
|
264
309
|
// console.debug('created bundles from proposals:', coreProposals, bundles);
|
|
265
|
-
return {
|
|
310
|
+
return harden({
|
|
266
311
|
bundles,
|
|
267
|
-
|
|
312
|
+
codeSteps,
|
|
268
313
|
bundleHandleToAbsolutePaths,
|
|
269
|
-
};
|
|
314
|
+
});
|
|
270
315
|
};
|