@akanjs/devkit 3.0.0-beta.6 → 3.0.0-beta.8
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 +2 -2
- package/subspace.test.ts +21 -0
- package/subspace.ts +33 -0
- package/subspaceConfig.ts +10 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/devkit",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.8",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@langchain/openai": "^1.4.6",
|
|
45
45
|
"@tailwindcss/node": "^4.3.0",
|
|
46
46
|
"@trapezedev/project": "^7.1.4",
|
|
47
|
-
"akanjs": "3.0.0-beta.
|
|
47
|
+
"akanjs": "3.0.0-beta.8",
|
|
48
48
|
"chalk": "^5.6.2",
|
|
49
49
|
"commander": "^14.0.3",
|
|
50
50
|
"dayjs": "^1.11.20",
|
package/subspace.test.ts
CHANGED
|
@@ -424,6 +424,27 @@ describe("SubspaceConfig", () => {
|
|
|
424
424
|
).toThrow(/duplicate subspace/);
|
|
425
425
|
});
|
|
426
426
|
|
|
427
|
+
test("refuses two subspaces on one cloud workspace, and takes a declaration with none", () => {
|
|
428
|
+
expect(
|
|
429
|
+
() =>
|
|
430
|
+
new SubspaceConfig({
|
|
431
|
+
subspaces: [
|
|
432
|
+
{ name: "a", repo: "a.git", apps: ["one"], workspaceId: "project" },
|
|
433
|
+
{ name: "b", repo: "b.git", apps: ["two"], workspaceId: "project" },
|
|
434
|
+
],
|
|
435
|
+
}),
|
|
436
|
+
).toThrow(/same workspaceId/);
|
|
437
|
+
expect(
|
|
438
|
+
() =>
|
|
439
|
+
new SubspaceConfig({
|
|
440
|
+
subspaces: [
|
|
441
|
+
{ name: "a", repo: "a.git", apps: ["one"] },
|
|
442
|
+
{ name: "b", repo: "b.git", apps: ["two"], workspaceId: "project" },
|
|
443
|
+
],
|
|
444
|
+
}),
|
|
445
|
+
).not.toThrow();
|
|
446
|
+
});
|
|
447
|
+
|
|
427
448
|
test("defaults the pushable branches and rejects anything else", () => {
|
|
428
449
|
const config = new SubspaceConfig({ subspaces: [{ name: "a", repo: "a.git", apps: ["one"] }] });
|
|
429
450
|
expect(config.pushableBranches).toEqual(SubspaceConfig.defaultPushableBranches);
|
package/subspace.ts
CHANGED
|
@@ -55,6 +55,17 @@ export interface SubspacePushResult {
|
|
|
55
55
|
prunedDependencies?: string[];
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
export interface SubspaceEnvUploadResult {
|
|
59
|
+
name: string;
|
|
60
|
+
/** The cloud workspace whose env archive was replaced: the subspace's own, never this workspace's. */
|
|
61
|
+
workspaceId: string;
|
|
62
|
+
host: string;
|
|
63
|
+
outcome: "uploaded" | "cancelled";
|
|
64
|
+
apps: string[];
|
|
65
|
+
libs: string[];
|
|
66
|
+
files: string[];
|
|
67
|
+
}
|
|
68
|
+
|
|
58
69
|
export interface SubspacePullResult {
|
|
59
70
|
name: string;
|
|
60
71
|
applied: string[];
|
|
@@ -100,6 +111,9 @@ export class Subspace {
|
|
|
100
111
|
get apps() {
|
|
101
112
|
return this.#declaration.apps;
|
|
102
113
|
}
|
|
114
|
+
get workspaceId() {
|
|
115
|
+
return this.#declaration.workspaceId;
|
|
116
|
+
}
|
|
103
117
|
get #remote() {
|
|
104
118
|
return `subspace-${this.#declaration.name}`;
|
|
105
119
|
}
|
|
@@ -700,6 +714,25 @@ export function formatSubspacePullResult(result: SubspacePullResult) {
|
|
|
700
714
|
return sections.join("\n");
|
|
701
715
|
}
|
|
702
716
|
|
|
717
|
+
export function formatSubspaceEnvUpload(result: SubspaceEnvUploadResult) {
|
|
718
|
+
const sections = [
|
|
719
|
+
`Akan Subspace Env Upload — ${result.name}`,
|
|
720
|
+
`cloud workspace: ${result.workspaceId} · host: ${result.host}`,
|
|
721
|
+
"",
|
|
722
|
+
...(result.outcome === "cancelled"
|
|
723
|
+
? [" cancelled — the subspace's env archive is untouched."]
|
|
724
|
+
: [
|
|
725
|
+
`Uploaded (${result.files.length}), replacing that workspace's whole archive:`,
|
|
726
|
+
"",
|
|
727
|
+
...result.files.map((file) => ` ${file}`),
|
|
728
|
+
"",
|
|
729
|
+
` apps: ${result.apps.join(", ")}`,
|
|
730
|
+
` libs: ${result.libs.join(", ") || "(none)"}`,
|
|
731
|
+
]),
|
|
732
|
+
];
|
|
733
|
+
return sections.join("\n");
|
|
734
|
+
}
|
|
735
|
+
|
|
703
736
|
export function formatSubspaceDiff(result: SubspaceDiffResult) {
|
|
704
737
|
const total = result.app.files.length + result.libs.files.length;
|
|
705
738
|
const sections = [
|
package/subspaceConfig.ts
CHANGED
|
@@ -37,6 +37,7 @@ export class SubspaceConfig {
|
|
|
37
37
|
#assertValid() {
|
|
38
38
|
const seenNames = new Set<string>();
|
|
39
39
|
const appOwners = new Map<string, string>();
|
|
40
|
+
const idOwners = new Map<string, string>();
|
|
40
41
|
for (const subspace of this.subspaces) {
|
|
41
42
|
if (!subspace.name || !subspace.repo)
|
|
42
43
|
throw new Error(`${SubspaceConfig.fileName}: every subspace needs a name and a repo`);
|
|
@@ -55,6 +56,15 @@ export class SubspaceConfig {
|
|
|
55
56
|
);
|
|
56
57
|
appOwners.set(app, subspace.name);
|
|
57
58
|
}
|
|
59
|
+
if (!subspace.workspaceId) continue;
|
|
60
|
+
const idOwner = idOwners.get(subspace.workspaceId);
|
|
61
|
+
//* An env upload replaces the cloud workspace's archive whole, so two subspaces sharing one would
|
|
62
|
+
//* each overwrite the other's values.
|
|
63
|
+
if (idOwner)
|
|
64
|
+
throw new Error(
|
|
65
|
+
`${SubspaceConfig.fileName}: subspaces "${idOwner}" and "${subspace.name}" declare the same workspaceId`,
|
|
66
|
+
);
|
|
67
|
+
idOwners.set(subspace.workspaceId, subspace.name);
|
|
58
68
|
}
|
|
59
69
|
}
|
|
60
70
|
|