@akanjs/devkit 3.0.2 → 3.1.0-rc.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/CHANGELOG.md +46 -7
- package/akanApp/akanApp.host.ts +3 -2
- package/akanConfig/akanConfig.test.ts +76 -6
- package/akanConfig/akanConfig.ts +111 -13
- package/akanConfig/akanWorkspaceConfig.test.ts +79 -0
- package/akanConfig/akanWorkspaceConfig.ts +63 -0
- package/akanConfig/index.ts +1 -0
- package/akanConfig/types.ts +23 -1
- package/akanContext.ts +1 -1
- package/applicationBuildRunner.test.ts +1 -1
- package/applicationBuildRunner.ts +73 -84
- package/artifact/implicitRootLayout.test.ts +6 -2
- package/artifact/implicitRootLayout.ts +12 -7
- package/biome.base.json +7 -2
- package/cloud/cloudApi.ts +82 -0
- package/cloud/globalConfig.ts +4 -0
- package/cloud/index.ts +1 -0
- package/cloud/updatePackUpload.test.ts +195 -0
- package/cloud/updatePackUpload.ts +115 -0
- package/commandDecorators/command.ts +8 -2
- package/commandDecorators/targetMeta.ts +1 -0
- package/executors.test.ts +21 -0
- package/executors.ts +9 -2
- package/frontendBuild/csrArtifactBuilder.ts +10 -1
- package/frontendBuild/cssCandidateCache.test.ts +10 -0
- package/frontendBuild/cssCandidateCache.ts +4 -2
- package/frontendBuild/pagesBundleBuilder.ts +5 -1
- package/frontendBuild/ssrBaseArtifactBuilder.ts +6 -2
- package/incrementalBuilder/buildBatch.proc.ts +14 -2
- package/incrementalBuilder/buildBatchProtocol.ts +3 -2
- package/incrementalBuilder/incrementalBuilder.proc.test.ts +96 -0
- package/incrementalBuilder/incrementalBuilder.proc.ts +30 -1
- package/lint/__fixtures__/no-import-external-library-in-test/bad.tsx +6 -0
- package/lint/__fixtures__/no-import-external-library-in-test/good.tsx +6 -0
- package/lint/no-import-external-library-in-test.grit +24 -0
- package/mobile/desktopServerStage.test.ts +6 -0
- package/mobile/desktopServerStage.ts +25 -3
- package/mobile/index.ts +1 -0
- package/mobile/nativeApp.test.ts +1 -0
- package/mobile/nativeApp.ts +96 -34
- package/mobile/nativeConfig.test.ts +59 -1
- package/mobile/nativeConfig.ts +13 -3
- package/mobile/serverBundleSecrets.test.ts +61 -0
- package/mobile/serverBundleSecrets.ts +85 -0
- package/mobile/updateUploader.test.ts +49 -0
- package/mobile/updateUploader.ts +71 -0
- package/package.json +3 -2
- package/pipeline/PipelineCompiler.test.ts +631 -0
- package/pipeline/PipelineCompiler.ts +646 -0
- package/pipeline/PipelineDefinition.test.ts +89 -0
- package/pipeline/PipelineDefinition.ts +117 -0
- package/pipeline/PipelineDryRun.test.ts +93 -0
- package/pipeline/PipelineDryRun.ts +89 -0
- package/pipeline/PipelineInputReader.ts +739 -0
- package/pipeline/index.ts +4 -0
- package/qualityScanner.test.ts +9 -3
- package/qualityScanner.ts +5 -2
- package/scanInfo.ts +13 -6
- package/subspace.test.ts +108 -4
- package/subspace.ts +162 -10
- package/subspaceConfig.ts +11 -14
- package/testHelpers.ts +4 -0
- package/transforms/externalizeFrameworkPlugin.ts +1 -7
- package/transforms/serverEnvPlugin.test.ts +93 -2
- package/transforms/serverEnvPlugin.ts +71 -18
- package/transforms/serverEnvProfile.test.ts +82 -0
- package/transforms/serverEnvProfile.ts +114 -0
- package/typecheck/projectTypecheck.test.ts +32 -0
- package/typecheck/projectTypecheck.ts +71 -0
- package/workspaceLayout.test.ts +26 -3
- package/workspaceLayout.ts +15 -4
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
3
|
+
/** What the uploader needs of an S3 client; Bun.S3Client is one. */
|
|
4
|
+
export interface UpdateBucket {
|
|
5
|
+
exists(key: string): Promise<boolean>;
|
|
6
|
+
write(key: string, data: Blob, options?: { type?: string }): Promise<number>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface UpdateUploadResult {
|
|
10
|
+
uploaded: number;
|
|
11
|
+
skipped: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//* A manifest names files that must already be there, so they go first and the manifests last, each signature before
|
|
15
|
+
//* its manifest as `publish-update` writes them. A release file never changes once published (its name carries its
|
|
16
|
+
//* hash), so one the bucket holds is skipped; a manifest is always written.
|
|
17
|
+
export class UpdateUploader {
|
|
18
|
+
static readonly #manifest = /\.json(?:\.sig)?$/;
|
|
19
|
+
|
|
20
|
+
/** `s3://bucket/prefix`: the credentials and endpoint come from S3_* (or AWS_*) in the environment. */
|
|
21
|
+
static parseTarget(target: string): { bucket: string; prefix: string } {
|
|
22
|
+
const match = /^s3:\/\/([^/]+)\/?(.*)$/.exec(target.trim());
|
|
23
|
+
if (!match?.[1]) throw new Error(`--upload takes s3://<bucket>/<prefix>, not ${JSON.stringify(target)}.`);
|
|
24
|
+
return { bucket: match[1], prefix: (match[2] ?? "").replace(/\/+$/, "") };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static order(files: string[]): { releases: string[]; manifests: string[] } {
|
|
28
|
+
const manifests = files.filter((file) => UpdateUploader.#manifest.test(file));
|
|
29
|
+
return {
|
|
30
|
+
releases: files.filter((file) => !UpdateUploader.#manifest.test(file)).sort((a, b) => a.localeCompare(b)),
|
|
31
|
+
manifests: manifests.sort(
|
|
32
|
+
(a, b) => Number(a.endsWith(".json")) - Number(b.endsWith(".json")) || a.localeCompare(b),
|
|
33
|
+
),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
constructor(
|
|
38
|
+
readonly bucket: UpdateBucket,
|
|
39
|
+
readonly prefix: string,
|
|
40
|
+
) {}
|
|
41
|
+
|
|
42
|
+
static forTarget(target: string): UpdateUploader {
|
|
43
|
+
const { bucket, prefix } = UpdateUploader.parseTarget(target);
|
|
44
|
+
return new UpdateUploader(new Bun.S3Client({ bucket }), prefix);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async upload(dir: string): Promise<UpdateUploadResult> {
|
|
48
|
+
const files: string[] = [];
|
|
49
|
+
for await (const file of new Bun.Glob("**/*").scan({ cwd: dir, onlyFiles: true })) {
|
|
50
|
+
if (!file.endsWith(".tmp")) files.push(file.split(path.sep).join("/"));
|
|
51
|
+
}
|
|
52
|
+
const { releases, manifests } = UpdateUploader.order(files);
|
|
53
|
+
const keyOf = (file: string) => (this.prefix ? `${this.prefix}/${file}` : file);
|
|
54
|
+
let uploaded = 0;
|
|
55
|
+
let skipped = 0;
|
|
56
|
+
for (const file of releases) {
|
|
57
|
+
if (await this.bucket.exists(keyOf(file))) {
|
|
58
|
+
skipped++;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
await this.bucket.write(keyOf(file), Bun.file(path.join(dir, file)));
|
|
62
|
+
uploaded++;
|
|
63
|
+
}
|
|
64
|
+
for (const file of manifests) {
|
|
65
|
+
const type = file.endsWith(".json") ? "application/json" : "text/plain";
|
|
66
|
+
await this.bucket.write(keyOf(file), Bun.file(path.join(dir, file)), { type });
|
|
67
|
+
uploaded++;
|
|
68
|
+
}
|
|
69
|
+
return { uploaded, skipped };
|
|
70
|
+
}
|
|
71
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/devkit",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.1.0-rc.0",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"./frontendBuild": "./frontendBuild/index.ts",
|
|
34
34
|
"./incrementalBuilder": "./incrementalBuilder/index.ts",
|
|
35
35
|
"./mobile": "./mobile/index.ts",
|
|
36
|
+
"./pipeline": "./pipeline/index.ts",
|
|
36
37
|
"./transforms": "./transforms/index.ts",
|
|
37
38
|
"./workflow": "./workflow/index.ts",
|
|
38
39
|
"./*.ts": "./*.ts",
|
|
@@ -47,7 +48,7 @@
|
|
|
47
48
|
"@earendil-works/pi-tui": "0.86.1",
|
|
48
49
|
"@inquirer/prompts": "^8.4.3",
|
|
49
50
|
"@tailwindcss/node": "^4.3.0",
|
|
50
|
-
"akanjs": "3.0.
|
|
51
|
+
"akanjs": "3.1.0-rc.0",
|
|
51
52
|
"chalk": "^5.6.2",
|
|
52
53
|
"commander": "^14.0.3",
|
|
53
54
|
"dayjs": "^1.11.20",
|