Skip to content

Commit eed1639

Browse files
committed
test(dogfood): export names withheld connector maps; both install modes name them; changeset
Claude-Session: https://claude.ai/code/session_01JQwxbYXRMR5S5B7JSmKkV7 Co-authored-by: Claude <noreply@anthropic.com>
1 parent db42dd2 commit eed1639

2 files changed

Lines changed: 44 additions & 21 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
'@objectstack/runtime': patch
3+
'@objectstack/cloud-connection': patch
4+
'@objectstack/spec': patch
5+
---
6+
7+
feat(runtime): a package export names each connector map it withheld, and both install modes of install-local name each one as incomplete
8+
9+
Clause-②: yes (widening)
10+
Metadata-protocol: none
11+
12+
`GET /api/v1/packages/:id/export` writes served items, and the served read withholds four connector maps whole: `providerConfig.headers`, `providerConfig.defaultHeaders`, `providerConfig.transport.headers` and `providerConfig.transport.env`. An exported connector used to arrive with such a map simply absent, so an import could not tell a withheld map from one the package never had. Now:
13+
14+
- **The export lists each one.** The manifest's `withheldMaps` (declared on `PackageExportManifestSchema`) holds `{ type: 'connector', name, path }` for every map withheld. Each exported connector's stored body is judged by the same `connector` redactor the served read ran, read through the protocol's by-name execution face. Only the position leaves that read: no header or variable name, and no value. A package that withheld nothing carries no key. An export that cannot judge (a protocol without `getMetaItemForExecution`, or a connector that read answers no body for) fails rather than omitting the key, because from an exporter that writes it, an absent key means nothing was withheld.
15+
- **Both install modes name each one.** `POST /api/v1/marketplace/install-local`, managed and unmanaged, accepts the package and answers `withheldMaps`, the list as the export wrote it, plus one `warn` line naming every map. The key is left out when the body carries no list, so that answer's key set is unchanged.
16+
- **One narrowing, at the door.** A `withheldMaps` value the export's declaration refuses is now answered `PLUGIN_MANIFEST_INVALID` (400 for an inline manifest, 502 for a cloud snapshot) before any write, in either mode, the way an invalid `installModes` already is. Before this change the door ignored the key, whatever its value. No export wrote the key before this release, so only a hand-written list can be refused. Fix: send the list exactly as the export wrote it, or drop it.
17+
- **Spec.** The `[PLANNED — not yet served]` marker is dropped from `withheldMaps`' describe, and the docblocks now say the key is served.

‎packages/qa/dogfood/test/export-withheld-connector-maps.dogfood.test.ts‎

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@
2121
// as served, no header name and no header value in the manifest;
2222
// 2. a MANAGED install of that export (the Studio import button's request)
2323
// answers 200 and names each map in `withheldMaps`, as the export wrote it;
24-
// 3. an UNMANAGED install of the same export answers 200 and names each map
25-
// the same way. The export carries no `installModes` (the per-package
26-
// export writes only its identity and collections, the family the
27-
// whole-deployment export card carries), so the test adds the key an
28-
// operator would add before importing it as a copy; the managed install
29-
// is removed first, because a managed package holds the namespace the
30-
// copy keeps.
24+
// 3. an UNMANAGED install of the same export, on a SECOND boot that never
25+
// held the package (the import "elsewhere" the export exists for),
26+
// answers 200 and names each map the same way. The per-package export
27+
// writes only its identity (`id`, `name`, `version`, `label`) and its
28+
// collections, so it carries neither `installModes` nor `type`, and the
29+
// copy refuses a body without them (measured: `manifest.type` refused);
30+
// that is the export's manifest-key family, not this file's. The test adds
31+
// the two keys an operator adds before importing an export as a copy.
3132
//
32-
// Boots a fixture stack of its own (the install-local plugin mounted), so it
33+
// Boots fixture stacks of its own (the install-local plugin mounted), so it
3334
// stays out of `SHARED_SHOWCASE`.
3435

3536
import { mkdtempSync, rmSync } from 'node:fs';
@@ -100,33 +101,39 @@ async function json(res: Response): Promise<Answer> {
100101

101102
describe('dogfood: a package export names each connector map it withheld, and both install modes name each as incomplete', () => {
102103
let stack: VerifyStack;
103-
let storageDir: string;
104+
let elsewhere: VerifyStack;
105+
const storageDirs: string[] = [];
104106
let source: Answer;
105107
let exported: Answer;
106108
let managed: Answer;
107-
let removed: Answer;
108109
let unmanaged: Answer;
109110

111+
const boot = async (): Promise<VerifyStack> => {
112+
const storageDir = mkdtempSync(join(tmpdir(), 'dogfood-export-withheld-maps-'));
113+
storageDirs.push(storageDir);
114+
return bootShowcase({ extraPlugins: [new MarketplaceInstallLocalPlugin({ controlPlaneUrl: 'off', storageDir })] });
115+
};
116+
110117
beforeAll(async () => {
111-
storageDir = mkdtempSync(join(tmpdir(), 'dogfood-export-withheld-maps-'));
112-
stack = await bootShowcase({
113-
extraPlugins: [new MarketplaceInstallLocalPlugin({ controlPlaneUrl: 'off', storageDir })],
114-
});
118+
stack = await boot();
115119
const token = await stack.signIn();
116120
source = await json(await stack.apiAs(token, 'POST', '/marketplace/install-local', SOURCE_BODY));
117121
exported = await json(await stack.apiAs(token, 'GET', `/packages/${encodeURIComponent(PACKAGE_ID)}/export`));
118122
const manifest = exported.body?.data ?? {};
119123
managed = await json(await stack.apiAs(token, 'POST', '/marketplace/install-local', { manifest }));
120-
removed = await json(await stack.apiAs(token, 'DELETE', `/marketplace/install-local/${encodeURIComponent(PACKAGE_ID)}`));
121-
unmanaged = await json(await stack.apiAs(token, 'POST', '/marketplace/install-local', {
122-
manifest: { ...manifest, installModes: ['managed', 'unmanaged'] },
124+
await stack.stop();
125+
126+
elsewhere = await boot();
127+
const other = await elsewhere.signIn();
128+
unmanaged = await json(await elsewhere.apiAs(other, 'POST', '/marketplace/install-local', {
129+
manifest: { ...manifest, type: 'app', installModes: ['managed', 'unmanaged'] },
123130
installMode: 'unmanaged',
124131
}));
125132
}, 300_000);
126133

127134
afterAll(async () => {
128-
await stack?.stop?.();
129-
if (storageDir) rmSync(storageDir, { recursive: true, force: true });
135+
await elsewhere?.stop?.();
136+
for (const dir of storageDirs) rmSync(dir, { recursive: true, force: true });
130137
});
131138

132139
it('the source package installs and its export answers 200', () => {
@@ -152,8 +159,7 @@ describe('dogfood: a package export names each connector map it withheld, and bo
152159
expect(managed.body?.data?.withheldMaps).toEqual(WITHHELD);
153160
});
154161

155-
it('3. an unmanaged install of the export answers 200 and names each map', () => {
156-
expect(removed.status, JSON.stringify(removed.body)).toBe(200);
162+
it('3. an unmanaged install of the export, on a boot that never held the package, answers 200 and names each map', () => {
157163
expect(unmanaged.status, JSON.stringify(unmanaged.body)).toBe(200);
158164
expect(unmanaged.body?.data?.installMode).toBe('unmanaged');
159165
expect(unmanaged.body?.data?.withheldMaps).toEqual(WITHHELD);

0 commit comments

Comments
 (0)