@akanjs/cli 2.1.0 → 2.1.1-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/README.ko.md +63 -0
- package/README.md +62 -0
- package/guidelines/componentRule/componentRule.generate.json +4 -10
- package/guidelines/cssRule/cssRule.generate.json +4 -10
- package/guidelines/docPageRule/docPageRule.generate.json +4 -10
- package/guidelines/docPageRule/docPageRule.instruction.md +1 -1
- package/guidelines/docSyncRule/docSyncRule.generate.json +4 -10
- package/guidelines/enumConstant/enumConstant.generate.json +4 -10
- package/guidelines/fieldRule/fieldRule.generate.json +4 -10
- package/guidelines/framework/framework.generate.json +4 -10
- package/guidelines/modelConstant/modelConstant.generate.json +4 -10
- package/guidelines/modelDictionary/modelDictionary.generate.json +4 -10
- package/guidelines/modelDocument/modelDocument.generate.json +4 -10
- package/guidelines/modelService/modelService.generate.json +4 -10
- package/guidelines/modelSignal/modelSignal.generate.json +4 -10
- package/guidelines/modelStore/modelStore.generate.json +4 -10
- package/guidelines/modelTemplate/modelTemplate.generate.json +4 -10
- package/guidelines/modelUnit/modelUnit.generate.json +4 -10
- package/guidelines/modelUtil/modelUtil.generate.json +4 -10
- package/guidelines/modelView/modelView.generate.json +4 -10
- package/guidelines/modelZone/modelZone.generate.json +4 -10
- package/guidelines/moduleCodegen/moduleCodegen.generate.json +4 -10
- package/guidelines/moduleOverview/moduleOverview.generate.json +4 -10
- package/guidelines/scalarConstant/scalarConstant.generate.json +4 -10
- package/guidelines/scalarDictionary/scalarDictionary.generate.json +4 -10
- package/guidelines/scalarModule/scalarModule.generate.json +4 -10
- package/guidelines/sharedUiUsage/sharedUiUsage.generate.json +4 -10
- package/guidelines/utilUiUsage/utilUiUsage.generate.json +4 -10
- package/incrementalBuilder.proc.js +131 -18
- package/index.js +201 -26
- package/package.json +3 -2
- package/templates/libRoot/lib/___libName__/__libName__.signal.ts +15 -0
|
@@ -24,9 +24,12 @@ import { mkdir } from "fs/promises";
|
|
|
24
24
|
var basePath = `${Bun.env.HOME ?? Bun.env.USERPROFILE}/.akan`;
|
|
25
25
|
var configPath = `${basePath}/config.json`;
|
|
26
26
|
var akanCloudHost = process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? "http://localhost" : "https://cloud.akanjs.com";
|
|
27
|
-
var akanCloudUrl = `${akanCloudHost}${process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? ":8282" : ""}
|
|
27
|
+
var akanCloudUrl = `${akanCloudHost}${process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? ":8282" : ""}/api`;
|
|
28
28
|
var defaultHostConfig = {};
|
|
29
|
-
var defaultAkanGlobalConfig = {
|
|
29
|
+
var defaultAkanGlobalConfig = {
|
|
30
|
+
cloudHost: {},
|
|
31
|
+
llm: null
|
|
32
|
+
};
|
|
30
33
|
|
|
31
34
|
// pkgs/@akanjs/devkit/fileSys.ts
|
|
32
35
|
import { stat } from "fs/promises";
|
|
@@ -2140,7 +2143,6 @@ class Executor {
|
|
|
2140
2143
|
this.logger = new Logger4(name);
|
|
2141
2144
|
this.logs = [];
|
|
2142
2145
|
this.cwdPath = cwdPath;
|
|
2143
|
-
//! TODO: 테스트 확인 필요
|
|
2144
2146
|
}
|
|
2145
2147
|
#stdout(data) {
|
|
2146
2148
|
if (Executor.verbose)
|
|
@@ -3982,6 +3984,16 @@ function findRootBoundaries(pageKeys, appCwdPath, basePaths) {
|
|
|
3982
3984
|
}
|
|
3983
3985
|
return [...boundaries.values()].sort((a, b) => a.segments.join("/").localeCompare(b.segments.join("/")));
|
|
3984
3986
|
}
|
|
3987
|
+
function hasAncestorRootBoundary(boundary, boundaries) {
|
|
3988
|
+
return boundaries.some((candidate) => candidate !== boundary && candidate.segments.length < boundary.segments.length && candidate.segments.every((segment, index) => boundary.segments[index] === segment));
|
|
3989
|
+
}
|
|
3990
|
+
function findExplicitRootLayoutAbsPath(pageKeys, appCwdPath) {
|
|
3991
|
+
const rootLayoutKey = pageKeys.find((key) => {
|
|
3992
|
+
const segments = getRootBoundarySegments(key);
|
|
3993
|
+
return segments !== null && segments.length === 0;
|
|
3994
|
+
});
|
|
3995
|
+
return rootLayoutKey ? path10.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
|
|
3996
|
+
}
|
|
3985
3997
|
function routePrefixForSegments(segments) {
|
|
3986
3998
|
const visible = segments.filter((segment) => !/^\(.+\)$/.test(segment));
|
|
3987
3999
|
return visible[0] ?? null;
|
|
@@ -3998,21 +4010,27 @@ async function writeGeneratedRootLayoutFile(opts) {
|
|
|
3998
4010
|
await mkdir3(path10.dirname(absPath), { recursive: true });
|
|
3999
4011
|
const sourceRel = opts.boundary.sourceAbsPath ? path10.relative(path10.dirname(absPath), opts.boundary.sourceAbsPath).split(path10.sep).join("/") : null;
|
|
4000
4012
|
const sourceSpecifier = sourceRel ? sourceRel.startsWith(".") ? sourceRel : `./${sourceRel}` : null;
|
|
4013
|
+
const inheritedSourceAbsPath = opts.rootSourceAbsPath && opts.rootSourceAbsPath !== opts.boundary.sourceAbsPath ? opts.rootSourceAbsPath : null;
|
|
4014
|
+
const inheritedSourceRel = inheritedSourceAbsPath ? path10.relative(path10.dirname(absPath), inheritedSourceAbsPath).split(path10.sep).join("/") : null;
|
|
4015
|
+
const inheritedSourceSpecifier = inheritedSourceRel ? inheritedSourceRel.startsWith(".") ? inheritedSourceRel : `./${inheritedSourceRel}` : null;
|
|
4001
4016
|
const clientImport = opts.includeStInit ? `import { st } from "@apps/${opts.appName}/client";
|
|
4002
4017
|
void st;
|
|
4003
4018
|
` : `import "@apps/${opts.appName}/client";
|
|
4019
|
+
`;
|
|
4020
|
+
const inheritedImport = inheritedSourceSpecifier ? `import * as inheritedLayout from ${JSON.stringify(inheritedSourceSpecifier)};
|
|
4021
|
+
` : `const inheritedLayout = {};
|
|
4004
4022
|
`;
|
|
4005
4023
|
const prefix = routePrefixForSegments(opts.boundary.segments);
|
|
4006
4024
|
const userImport = sourceSpecifier ? `import UserLayout, * as userLayout from ${JSON.stringify(sourceSpecifier)};
|
|
4007
4025
|
` : `const UserLayout = ({ children }) => children;
|
|
4008
4026
|
const userLayout = {};
|
|
4009
4027
|
`;
|
|
4010
|
-
const source = `import type { LayoutProps, PageProps } from "akanjs/client";
|
|
4028
|
+
const source = opts.includeSystemProvider ? `import type { LayoutProps, PageProps } from "akanjs/client";
|
|
4011
4029
|
import { loadFonts } from "akanjs/client";
|
|
4012
4030
|
import { System } from "akanjs/ui";
|
|
4013
4031
|
import { env } from "@apps/${opts.appName}/env/env.client";
|
|
4014
|
-
${clientImport}${userImport}
|
|
4015
|
-
const userFonts = userLayout.fonts ?? [];
|
|
4032
|
+
${clientImport}${inheritedImport}${userImport}
|
|
4033
|
+
const userFonts = userLayout.fonts ?? inheritedLayout.fonts ?? [];
|
|
4016
4034
|
const defaultFonts = userFonts.filter((font) => font.default);
|
|
4017
4035
|
if (defaultFonts.length > 1) throw new Error("[route-convention] only one default font is allowed per root layout");
|
|
4018
4036
|
const defaultFont = defaultFonts[0];
|
|
@@ -4020,7 +4038,9 @@ const defaultFontClassName = defaultFont ? (defaultFont.className ?? \`font-\${d
|
|
|
4020
4038
|
|
|
4021
4039
|
export async function generateHead(props: PageProps) {
|
|
4022
4040
|
if (userLayout.generateHead) return userLayout.generateHead(props);
|
|
4023
|
-
return userLayout.head;
|
|
4041
|
+
if (userLayout.head !== undefined) return userLayout.head;
|
|
4042
|
+
if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
|
|
4043
|
+
return inheritedLayout.head;
|
|
4024
4044
|
}
|
|
4025
4045
|
|
|
4026
4046
|
export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
|
|
@@ -4030,19 +4050,31 @@ export default function GeneratedLayout({ children, params, searchParams }: Layo
|
|
|
4030
4050
|
appName=${JSON.stringify(opts.appName)}
|
|
4031
4051
|
${prefix ? `prefix=${JSON.stringify(prefix)}
|
|
4032
4052
|
` : ""}params={params}
|
|
4033
|
-
manifest={userLayout.manifest}
|
|
4053
|
+
manifest={userLayout.manifest ?? inheritedLayout.manifest}
|
|
4034
4054
|
env={env}
|
|
4035
|
-
theme={userLayout.theme}
|
|
4055
|
+
theme={userLayout.theme ?? inheritedLayout.theme}
|
|
4036
4056
|
fonts={loadFonts(userFonts)}
|
|
4037
4057
|
className={defaultFontClassName}
|
|
4038
|
-
gaTrackingId={userLayout.gaTrackingId}
|
|
4039
|
-
layoutStyle={userLayout.layoutStyle}
|
|
4040
|
-
reconnect={userLayout.reconnect ?? false}
|
|
4058
|
+
gaTrackingId={userLayout.gaTrackingId ?? inheritedLayout.gaTrackingId}
|
|
4059
|
+
layoutStyle={userLayout.layoutStyle ?? inheritedLayout.layoutStyle}
|
|
4060
|
+
reconnect={userLayout.reconnect ?? inheritedLayout.reconnect ?? false}
|
|
4041
4061
|
>
|
|
4042
4062
|
<UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>
|
|
4043
4063
|
</System.Provider>
|
|
4044
4064
|
);
|
|
4045
4065
|
}
|
|
4066
|
+
` : `import type { LayoutProps, PageProps } from "akanjs/client";
|
|
4067
|
+
${inheritedImport}${userImport}
|
|
4068
|
+
export async function generateHead(props: PageProps) {
|
|
4069
|
+
if (userLayout.generateHead) return userLayout.generateHead(props);
|
|
4070
|
+
if (userLayout.head !== undefined) return userLayout.head;
|
|
4071
|
+
if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
|
|
4072
|
+
return inheritedLayout.head;
|
|
4073
|
+
}
|
|
4074
|
+
|
|
4075
|
+
export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
|
|
4076
|
+
return <UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>;
|
|
4077
|
+
}
|
|
4046
4078
|
`;
|
|
4047
4079
|
await Bun.write(absPath, source);
|
|
4048
4080
|
return absPath;
|
|
@@ -4051,6 +4083,8 @@ async function resolveSsrPageEntries(opts) {
|
|
|
4051
4083
|
const absPageDir = path10.resolve(opts.appCwdPath, "page");
|
|
4052
4084
|
const hasSt = await appHasStModule(opts.appCwdPath);
|
|
4053
4085
|
const basePaths = opts.basePaths ?? [];
|
|
4086
|
+
const rootSourceAbsPath = findExplicitRootLayoutAbsPath(opts.pageKeys, opts.appCwdPath);
|
|
4087
|
+
const rootBoundaries = findRootBoundaries(opts.pageKeys, opts.appCwdPath, basePaths);
|
|
4054
4088
|
const rootLayoutKeys = new Set(opts.pageKeys.filter((key) => {
|
|
4055
4089
|
const segments = getRootBoundarySegments(key);
|
|
4056
4090
|
return segments !== null && isRootBoundarySegments(segments, basePaths);
|
|
@@ -4059,15 +4093,17 @@ async function resolveSsrPageEntries(opts) {
|
|
|
4059
4093
|
key,
|
|
4060
4094
|
moduleAbsPath: path10.resolve(absPageDir, key)
|
|
4061
4095
|
}));
|
|
4062
|
-
const generated = await Promise.all(
|
|
4096
|
+
const generated = await Promise.all(rootBoundaries.map(async (boundary) => ({
|
|
4063
4097
|
key: implicitRootLayoutKey(boundary.segments),
|
|
4064
4098
|
moduleAbsPath: await writeGeneratedRootLayoutFile({
|
|
4065
4099
|
appCwdPath: opts.appCwdPath,
|
|
4066
4100
|
appName: opts.appName,
|
|
4067
4101
|
boundary,
|
|
4068
|
-
|
|
4102
|
+
rootSourceAbsPath,
|
|
4103
|
+
includeStInit: hasSt && boundary.segments.length === 0,
|
|
4104
|
+
includeSystemProvider: !hasAncestorRootBoundary(boundary, rootBoundaries)
|
|
4069
4105
|
}),
|
|
4070
|
-
seedAbsPaths:
|
|
4106
|
+
seedAbsPaths: [...new Set([boundary.sourceAbsPath, rootSourceAbsPath].filter((absPath) => absPath !== null))]
|
|
4071
4107
|
})));
|
|
4072
4108
|
const entries = [...base, ...generated];
|
|
4073
4109
|
entries.sort((a, b) => a.key.localeCompare(b.key));
|
|
@@ -7042,6 +7078,13 @@ function formatBytes(bytes) {
|
|
|
7042
7078
|
}
|
|
7043
7079
|
// pkgs/@akanjs/devkit/frontendBuild/ssrBaseArtifactBuilder.ts
|
|
7044
7080
|
import path30 from "path";
|
|
7081
|
+
import { optimize } from "@tailwindcss/node";
|
|
7082
|
+
function prepareCssAsset(command, basePath2, cssText) {
|
|
7083
|
+
if (command !== "build")
|
|
7084
|
+
return cssText;
|
|
7085
|
+
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: true }).code;
|
|
7086
|
+
}
|
|
7087
|
+
|
|
7045
7088
|
class SsrBaseArtifactBuilder {
|
|
7046
7089
|
#app;
|
|
7047
7090
|
#command;
|
|
@@ -7133,14 +7176,15 @@ class SsrBaseArtifactBuilder {
|
|
|
7133
7176
|
}
|
|
7134
7177
|
async#writeCssAsset(basePath2, cssText) {
|
|
7135
7178
|
const cssAssetName = basePath2 || "root";
|
|
7179
|
+
const preparedCssText = await prepareCssAsset(this.#command, basePath2, cssText);
|
|
7136
7180
|
const cssHash = Bun.hash(`${basePath2}
|
|
7137
|
-
${
|
|
7181
|
+
${preparedCssText}`).toString(36);
|
|
7138
7182
|
const [cssRelPath, cssUrl] = [
|
|
7139
7183
|
`styles/${cssAssetName}-${cssHash}.css`,
|
|
7140
7184
|
`/_akan/styles/${cssAssetName}-${cssHash}.css`
|
|
7141
7185
|
];
|
|
7142
|
-
await Bun.write(path30.join(this.#absArtifactDir, cssRelPath),
|
|
7143
|
-
this.#app.verbose(`[base-artifact] wrote ${
|
|
7186
|
+
await Bun.write(path30.join(this.#absArtifactDir, cssRelPath), preparedCssText);
|
|
7187
|
+
this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath2} -> ${cssRelPath}`);
|
|
7144
7188
|
return [basePath2, { cssUrl, cssRelPath }];
|
|
7145
7189
|
}
|
|
7146
7190
|
}
|
|
@@ -9407,6 +9451,75 @@ import { Box as Box2, Newline, Text as Text2, useInput as useInput2 } from "ink"
|
|
|
9407
9451
|
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
9408
9452
|
import { jsxDEV as jsxDEV2, Fragment as Fragment2 } from "react/jsx-dev-runtime";
|
|
9409
9453
|
"use client";
|
|
9454
|
+
// pkgs/@akanjs/devkit/cloud/cloudApi.ts
|
|
9455
|
+
class HttpClient2 {
|
|
9456
|
+
baseUrl;
|
|
9457
|
+
constructor(baseUrl) {
|
|
9458
|
+
this.baseUrl = baseUrl;
|
|
9459
|
+
}
|
|
9460
|
+
async get(url, { headers } = {}) {
|
|
9461
|
+
const response = await fetch(`${this.baseUrl}${url}`, {
|
|
9462
|
+
headers: { "Content-Type": "application/json", ...headers }
|
|
9463
|
+
});
|
|
9464
|
+
return response.json();
|
|
9465
|
+
}
|
|
9466
|
+
async post(url, data, { headers } = {}) {
|
|
9467
|
+
const isFormData = data instanceof FormData;
|
|
9468
|
+
const response = await fetch(`${this.baseUrl}${url}`, {
|
|
9469
|
+
method: "POST",
|
|
9470
|
+
body: isFormData ? data : JSON.stringify(data),
|
|
9471
|
+
headers: isFormData ? headers : { "Content-Type": "application/json", ...headers }
|
|
9472
|
+
});
|
|
9473
|
+
return response.json();
|
|
9474
|
+
}
|
|
9475
|
+
}
|
|
9476
|
+
|
|
9477
|
+
class CloudApi {
|
|
9478
|
+
api;
|
|
9479
|
+
#accessToken = null;
|
|
9480
|
+
constructor(host, { accessToken } = {}) {
|
|
9481
|
+
this.api = new HttpClient2(`${host}/api`);
|
|
9482
|
+
this.#accessToken = accessToken ?? null;
|
|
9483
|
+
}
|
|
9484
|
+
async uploadEnv(devProjectId, fileStream) {
|
|
9485
|
+
const formData = new FormData;
|
|
9486
|
+
formData.append("devProjectId", devProjectId);
|
|
9487
|
+
formData.append("fileStream", await new Response(fileStream).blob());
|
|
9488
|
+
const response = await this.api.post(`/uploadEnv/${devProjectId}`, formData);
|
|
9489
|
+
return response.success;
|
|
9490
|
+
}
|
|
9491
|
+
async downloadEnv(devProjectId) {
|
|
9492
|
+
const response = await this.api.get(`/downloadEnv/${devProjectId}`);
|
|
9493
|
+
return response.success;
|
|
9494
|
+
}
|
|
9495
|
+
async getRemoteAuthToken(remoteId) {
|
|
9496
|
+
if (this.#needRefreshToken())
|
|
9497
|
+
return await this.refreshAuthToken();
|
|
9498
|
+
else if (this.#accessToken)
|
|
9499
|
+
return this.#accessToken;
|
|
9500
|
+
const accessToken = await this.api.get(`/getRemoteAuthToken/${remoteId}`);
|
|
9501
|
+
this.#accessToken = {
|
|
9502
|
+
jwt: accessToken.jwt,
|
|
9503
|
+
refreshToken: accessToken.refreshToken,
|
|
9504
|
+
expiresAt: new Date(accessToken.expiresAt)
|
|
9505
|
+
};
|
|
9506
|
+
return accessToken;
|
|
9507
|
+
}
|
|
9508
|
+
async refreshAuthToken() {
|
|
9509
|
+
const response = await this.api.post(`/refreshRemoteAuthToken`, {
|
|
9510
|
+
refreshToken: this.#accessToken?.refreshToken
|
|
9511
|
+
});
|
|
9512
|
+
this.#accessToken = {
|
|
9513
|
+
jwt: response.jwt,
|
|
9514
|
+
refreshToken: response.refreshToken,
|
|
9515
|
+
expiresAt: new Date(response.expiresAt)
|
|
9516
|
+
};
|
|
9517
|
+
return response;
|
|
9518
|
+
}
|
|
9519
|
+
#needRefreshToken() {
|
|
9520
|
+
return !!(this.#accessToken?.expiresAt && this.#accessToken.expiresAt.getTime() < Date.now() - 1000 * 60 * 60);
|
|
9521
|
+
}
|
|
9522
|
+
}
|
|
9410
9523
|
// pkgs/@akanjs/devkit/incrementalBuilder/incrementalBuilder.proc.ts
|
|
9411
9524
|
import { Logger as Logger12 } from "akanjs/common";
|
|
9412
9525
|
|
package/index.js
CHANGED
|
@@ -22,9 +22,12 @@ import { mkdir } from "fs/promises";
|
|
|
22
22
|
var basePath = `${Bun.env.HOME ?? Bun.env.USERPROFILE}/.akan`;
|
|
23
23
|
var configPath = `${basePath}/config.json`;
|
|
24
24
|
var akanCloudHost = process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? "http://localhost" : "https://cloud.akanjs.com";
|
|
25
|
-
var akanCloudUrl = `${akanCloudHost}${process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? ":8282" : ""}
|
|
25
|
+
var akanCloudUrl = `${akanCloudHost}${process.env.AKAN_PUBLIC_OPERATION_MODE === "local" ? ":8282" : ""}/api`;
|
|
26
26
|
var defaultHostConfig = {};
|
|
27
|
-
var defaultAkanGlobalConfig = {
|
|
27
|
+
var defaultAkanGlobalConfig = {
|
|
28
|
+
cloudHost: {},
|
|
29
|
+
llm: null
|
|
30
|
+
};
|
|
28
31
|
|
|
29
32
|
// pkgs/@akanjs/devkit/fileSys.ts
|
|
30
33
|
import { stat } from "fs/promises";
|
|
@@ -2138,7 +2141,6 @@ class Executor {
|
|
|
2138
2141
|
this.logger = new Logger4(name);
|
|
2139
2142
|
this.logs = [];
|
|
2140
2143
|
this.cwdPath = cwdPath;
|
|
2141
|
-
//! TODO: 테스트 확인 필요
|
|
2142
2144
|
}
|
|
2143
2145
|
#stdout(data) {
|
|
2144
2146
|
if (Executor.verbose)
|
|
@@ -3980,6 +3982,16 @@ function findRootBoundaries(pageKeys, appCwdPath, basePaths) {
|
|
|
3980
3982
|
}
|
|
3981
3983
|
return [...boundaries.values()].sort((a, b) => a.segments.join("/").localeCompare(b.segments.join("/")));
|
|
3982
3984
|
}
|
|
3985
|
+
function hasAncestorRootBoundary(boundary, boundaries) {
|
|
3986
|
+
return boundaries.some((candidate) => candidate !== boundary && candidate.segments.length < boundary.segments.length && candidate.segments.every((segment, index) => boundary.segments[index] === segment));
|
|
3987
|
+
}
|
|
3988
|
+
function findExplicitRootLayoutAbsPath(pageKeys, appCwdPath) {
|
|
3989
|
+
const rootLayoutKey = pageKeys.find((key) => {
|
|
3990
|
+
const segments = getRootBoundarySegments(key);
|
|
3991
|
+
return segments !== null && segments.length === 0;
|
|
3992
|
+
});
|
|
3993
|
+
return rootLayoutKey ? path10.resolve(appCwdPath, "page", rootLayoutKey.replace(/^\.\//, "")) : null;
|
|
3994
|
+
}
|
|
3983
3995
|
function routePrefixForSegments(segments) {
|
|
3984
3996
|
const visible = segments.filter((segment) => !/^\(.+\)$/.test(segment));
|
|
3985
3997
|
return visible[0] ?? null;
|
|
@@ -3996,21 +4008,27 @@ async function writeGeneratedRootLayoutFile(opts) {
|
|
|
3996
4008
|
await mkdir3(path10.dirname(absPath), { recursive: true });
|
|
3997
4009
|
const sourceRel = opts.boundary.sourceAbsPath ? path10.relative(path10.dirname(absPath), opts.boundary.sourceAbsPath).split(path10.sep).join("/") : null;
|
|
3998
4010
|
const sourceSpecifier = sourceRel ? sourceRel.startsWith(".") ? sourceRel : `./${sourceRel}` : null;
|
|
4011
|
+
const inheritedSourceAbsPath = opts.rootSourceAbsPath && opts.rootSourceAbsPath !== opts.boundary.sourceAbsPath ? opts.rootSourceAbsPath : null;
|
|
4012
|
+
const inheritedSourceRel = inheritedSourceAbsPath ? path10.relative(path10.dirname(absPath), inheritedSourceAbsPath).split(path10.sep).join("/") : null;
|
|
4013
|
+
const inheritedSourceSpecifier = inheritedSourceRel ? inheritedSourceRel.startsWith(".") ? inheritedSourceRel : `./${inheritedSourceRel}` : null;
|
|
3999
4014
|
const clientImport = opts.includeStInit ? `import { st } from "@apps/${opts.appName}/client";
|
|
4000
4015
|
void st;
|
|
4001
4016
|
` : `import "@apps/${opts.appName}/client";
|
|
4017
|
+
`;
|
|
4018
|
+
const inheritedImport = inheritedSourceSpecifier ? `import * as inheritedLayout from ${JSON.stringify(inheritedSourceSpecifier)};
|
|
4019
|
+
` : `const inheritedLayout = {};
|
|
4002
4020
|
`;
|
|
4003
4021
|
const prefix = routePrefixForSegments(opts.boundary.segments);
|
|
4004
4022
|
const userImport = sourceSpecifier ? `import UserLayout, * as userLayout from ${JSON.stringify(sourceSpecifier)};
|
|
4005
4023
|
` : `const UserLayout = ({ children }) => children;
|
|
4006
4024
|
const userLayout = {};
|
|
4007
4025
|
`;
|
|
4008
|
-
const source = `import type { LayoutProps, PageProps } from "akanjs/client";
|
|
4026
|
+
const source = opts.includeSystemProvider ? `import type { LayoutProps, PageProps } from "akanjs/client";
|
|
4009
4027
|
import { loadFonts } from "akanjs/client";
|
|
4010
4028
|
import { System } from "akanjs/ui";
|
|
4011
4029
|
import { env } from "@apps/${opts.appName}/env/env.client";
|
|
4012
|
-
${clientImport}${userImport}
|
|
4013
|
-
const userFonts = userLayout.fonts ?? [];
|
|
4030
|
+
${clientImport}${inheritedImport}${userImport}
|
|
4031
|
+
const userFonts = userLayout.fonts ?? inheritedLayout.fonts ?? [];
|
|
4014
4032
|
const defaultFonts = userFonts.filter((font) => font.default);
|
|
4015
4033
|
if (defaultFonts.length > 1) throw new Error("[route-convention] only one default font is allowed per root layout");
|
|
4016
4034
|
const defaultFont = defaultFonts[0];
|
|
@@ -4018,7 +4036,9 @@ const defaultFontClassName = defaultFont ? (defaultFont.className ?? \`font-\${d
|
|
|
4018
4036
|
|
|
4019
4037
|
export async function generateHead(props: PageProps) {
|
|
4020
4038
|
if (userLayout.generateHead) return userLayout.generateHead(props);
|
|
4021
|
-
return userLayout.head;
|
|
4039
|
+
if (userLayout.head !== undefined) return userLayout.head;
|
|
4040
|
+
if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
|
|
4041
|
+
return inheritedLayout.head;
|
|
4022
4042
|
}
|
|
4023
4043
|
|
|
4024
4044
|
export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
|
|
@@ -4028,19 +4048,31 @@ export default function GeneratedLayout({ children, params, searchParams }: Layo
|
|
|
4028
4048
|
appName=${JSON.stringify(opts.appName)}
|
|
4029
4049
|
${prefix ? `prefix=${JSON.stringify(prefix)}
|
|
4030
4050
|
` : ""}params={params}
|
|
4031
|
-
manifest={userLayout.manifest}
|
|
4051
|
+
manifest={userLayout.manifest ?? inheritedLayout.manifest}
|
|
4032
4052
|
env={env}
|
|
4033
|
-
theme={userLayout.theme}
|
|
4053
|
+
theme={userLayout.theme ?? inheritedLayout.theme}
|
|
4034
4054
|
fonts={loadFonts(userFonts)}
|
|
4035
4055
|
className={defaultFontClassName}
|
|
4036
|
-
gaTrackingId={userLayout.gaTrackingId}
|
|
4037
|
-
layoutStyle={userLayout.layoutStyle}
|
|
4038
|
-
reconnect={userLayout.reconnect ?? false}
|
|
4056
|
+
gaTrackingId={userLayout.gaTrackingId ?? inheritedLayout.gaTrackingId}
|
|
4057
|
+
layoutStyle={userLayout.layoutStyle ?? inheritedLayout.layoutStyle}
|
|
4058
|
+
reconnect={userLayout.reconnect ?? inheritedLayout.reconnect ?? false}
|
|
4039
4059
|
>
|
|
4040
4060
|
<UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>
|
|
4041
4061
|
</System.Provider>
|
|
4042
4062
|
);
|
|
4043
4063
|
}
|
|
4064
|
+
` : `import type { LayoutProps, PageProps } from "akanjs/client";
|
|
4065
|
+
${inheritedImport}${userImport}
|
|
4066
|
+
export async function generateHead(props: PageProps) {
|
|
4067
|
+
if (userLayout.generateHead) return userLayout.generateHead(props);
|
|
4068
|
+
if (userLayout.head !== undefined) return userLayout.head;
|
|
4069
|
+
if (inheritedLayout.generateHead) return inheritedLayout.generateHead(props);
|
|
4070
|
+
return inheritedLayout.head;
|
|
4071
|
+
}
|
|
4072
|
+
|
|
4073
|
+
export default function GeneratedLayout({ children, params, searchParams }: LayoutProps) {
|
|
4074
|
+
return <UserLayout params={params} searchParams={searchParams}>{children}</UserLayout>;
|
|
4075
|
+
}
|
|
4044
4076
|
`;
|
|
4045
4077
|
await Bun.write(absPath, source);
|
|
4046
4078
|
return absPath;
|
|
@@ -4049,6 +4081,8 @@ async function resolveSsrPageEntries(opts) {
|
|
|
4049
4081
|
const absPageDir = path10.resolve(opts.appCwdPath, "page");
|
|
4050
4082
|
const hasSt = await appHasStModule(opts.appCwdPath);
|
|
4051
4083
|
const basePaths = opts.basePaths ?? [];
|
|
4084
|
+
const rootSourceAbsPath = findExplicitRootLayoutAbsPath(opts.pageKeys, opts.appCwdPath);
|
|
4085
|
+
const rootBoundaries = findRootBoundaries(opts.pageKeys, opts.appCwdPath, basePaths);
|
|
4052
4086
|
const rootLayoutKeys = new Set(opts.pageKeys.filter((key) => {
|
|
4053
4087
|
const segments = getRootBoundarySegments(key);
|
|
4054
4088
|
return segments !== null && isRootBoundarySegments(segments, basePaths);
|
|
@@ -4057,15 +4091,17 @@ async function resolveSsrPageEntries(opts) {
|
|
|
4057
4091
|
key,
|
|
4058
4092
|
moduleAbsPath: path10.resolve(absPageDir, key)
|
|
4059
4093
|
}));
|
|
4060
|
-
const generated = await Promise.all(
|
|
4094
|
+
const generated = await Promise.all(rootBoundaries.map(async (boundary) => ({
|
|
4061
4095
|
key: implicitRootLayoutKey(boundary.segments),
|
|
4062
4096
|
moduleAbsPath: await writeGeneratedRootLayoutFile({
|
|
4063
4097
|
appCwdPath: opts.appCwdPath,
|
|
4064
4098
|
appName: opts.appName,
|
|
4065
4099
|
boundary,
|
|
4066
|
-
|
|
4100
|
+
rootSourceAbsPath,
|
|
4101
|
+
includeStInit: hasSt && boundary.segments.length === 0,
|
|
4102
|
+
includeSystemProvider: !hasAncestorRootBoundary(boundary, rootBoundaries)
|
|
4067
4103
|
}),
|
|
4068
|
-
seedAbsPaths:
|
|
4104
|
+
seedAbsPaths: [...new Set([boundary.sourceAbsPath, rootSourceAbsPath].filter((absPath) => absPath !== null))]
|
|
4069
4105
|
})));
|
|
4070
4106
|
const entries = [...base, ...generated];
|
|
4071
4107
|
entries.sort((a, b) => a.key.localeCompare(b.key));
|
|
@@ -7040,6 +7076,13 @@ function formatBytes(bytes) {
|
|
|
7040
7076
|
}
|
|
7041
7077
|
// pkgs/@akanjs/devkit/frontendBuild/ssrBaseArtifactBuilder.ts
|
|
7042
7078
|
import path30 from "path";
|
|
7079
|
+
import { optimize } from "@tailwindcss/node";
|
|
7080
|
+
function prepareCssAsset(command, basePath2, cssText) {
|
|
7081
|
+
if (command !== "build")
|
|
7082
|
+
return cssText;
|
|
7083
|
+
return optimize(cssText, { file: `${basePath2 || "root"}.css`, minify: true }).code;
|
|
7084
|
+
}
|
|
7085
|
+
|
|
7043
7086
|
class SsrBaseArtifactBuilder {
|
|
7044
7087
|
#app;
|
|
7045
7088
|
#command;
|
|
@@ -7131,14 +7174,15 @@ class SsrBaseArtifactBuilder {
|
|
|
7131
7174
|
}
|
|
7132
7175
|
async#writeCssAsset(basePath2, cssText) {
|
|
7133
7176
|
const cssAssetName = basePath2 || "root";
|
|
7177
|
+
const preparedCssText = await prepareCssAsset(this.#command, basePath2, cssText);
|
|
7134
7178
|
const cssHash = Bun.hash(`${basePath2}
|
|
7135
|
-
${
|
|
7179
|
+
${preparedCssText}`).toString(36);
|
|
7136
7180
|
const [cssRelPath, cssUrl] = [
|
|
7137
7181
|
`styles/${cssAssetName}-${cssHash}.css`,
|
|
7138
7182
|
`/_akan/styles/${cssAssetName}-${cssHash}.css`
|
|
7139
7183
|
];
|
|
7140
|
-
await Bun.write(path30.join(this.#absArtifactDir, cssRelPath),
|
|
7141
|
-
this.#app.verbose(`[base-artifact] wrote ${
|
|
7184
|
+
await Bun.write(path30.join(this.#absArtifactDir, cssRelPath), preparedCssText);
|
|
7185
|
+
this.#app.verbose(`[base-artifact] wrote ${preparedCssText.length} bytes of CSS for ${basePath2} -> ${cssRelPath}`);
|
|
7142
7186
|
return [basePath2, { cssUrl, cssRelPath }];
|
|
7143
7187
|
}
|
|
7144
7188
|
}
|
|
@@ -9405,6 +9449,75 @@ import { Box as Box2, Newline, Text as Text2, useInput as useInput2 } from "ink"
|
|
|
9405
9449
|
import { useEffect as useEffect3, useState as useState3 } from "react";
|
|
9406
9450
|
import { jsxDEV as jsxDEV2, Fragment as Fragment2 } from "react/jsx-dev-runtime";
|
|
9407
9451
|
"use client";
|
|
9452
|
+
// pkgs/@akanjs/devkit/cloud/cloudApi.ts
|
|
9453
|
+
class HttpClient2 {
|
|
9454
|
+
baseUrl;
|
|
9455
|
+
constructor(baseUrl) {
|
|
9456
|
+
this.baseUrl = baseUrl;
|
|
9457
|
+
}
|
|
9458
|
+
async get(url, { headers } = {}) {
|
|
9459
|
+
const response = await fetch(`${this.baseUrl}${url}`, {
|
|
9460
|
+
headers: { "Content-Type": "application/json", ...headers }
|
|
9461
|
+
});
|
|
9462
|
+
return response.json();
|
|
9463
|
+
}
|
|
9464
|
+
async post(url, data, { headers } = {}) {
|
|
9465
|
+
const isFormData = data instanceof FormData;
|
|
9466
|
+
const response = await fetch(`${this.baseUrl}${url}`, {
|
|
9467
|
+
method: "POST",
|
|
9468
|
+
body: isFormData ? data : JSON.stringify(data),
|
|
9469
|
+
headers: isFormData ? headers : { "Content-Type": "application/json", ...headers }
|
|
9470
|
+
});
|
|
9471
|
+
return response.json();
|
|
9472
|
+
}
|
|
9473
|
+
}
|
|
9474
|
+
|
|
9475
|
+
class CloudApi {
|
|
9476
|
+
api;
|
|
9477
|
+
#accessToken = null;
|
|
9478
|
+
constructor(host, { accessToken } = {}) {
|
|
9479
|
+
this.api = new HttpClient2(`${host}/api`);
|
|
9480
|
+
this.#accessToken = accessToken ?? null;
|
|
9481
|
+
}
|
|
9482
|
+
async uploadEnv(devProjectId, fileStream) {
|
|
9483
|
+
const formData = new FormData;
|
|
9484
|
+
formData.append("devProjectId", devProjectId);
|
|
9485
|
+
formData.append("fileStream", await new Response(fileStream).blob());
|
|
9486
|
+
const response = await this.api.post(`/uploadEnv/${devProjectId}`, formData);
|
|
9487
|
+
return response.success;
|
|
9488
|
+
}
|
|
9489
|
+
async downloadEnv(devProjectId) {
|
|
9490
|
+
const response = await this.api.get(`/downloadEnv/${devProjectId}`);
|
|
9491
|
+
return response.success;
|
|
9492
|
+
}
|
|
9493
|
+
async getRemoteAuthToken(remoteId) {
|
|
9494
|
+
if (this.#needRefreshToken())
|
|
9495
|
+
return await this.refreshAuthToken();
|
|
9496
|
+
else if (this.#accessToken)
|
|
9497
|
+
return this.#accessToken;
|
|
9498
|
+
const accessToken = await this.api.get(`/getRemoteAuthToken/${remoteId}`);
|
|
9499
|
+
this.#accessToken = {
|
|
9500
|
+
jwt: accessToken.jwt,
|
|
9501
|
+
refreshToken: accessToken.refreshToken,
|
|
9502
|
+
expiresAt: new Date(accessToken.expiresAt)
|
|
9503
|
+
};
|
|
9504
|
+
return accessToken;
|
|
9505
|
+
}
|
|
9506
|
+
async refreshAuthToken() {
|
|
9507
|
+
const response = await this.api.post(`/refreshRemoteAuthToken`, {
|
|
9508
|
+
refreshToken: this.#accessToken?.refreshToken
|
|
9509
|
+
});
|
|
9510
|
+
this.#accessToken = {
|
|
9511
|
+
jwt: response.jwt,
|
|
9512
|
+
refreshToken: response.refreshToken,
|
|
9513
|
+
expiresAt: new Date(response.expiresAt)
|
|
9514
|
+
};
|
|
9515
|
+
return response;
|
|
9516
|
+
}
|
|
9517
|
+
#needRefreshToken() {
|
|
9518
|
+
return !!(this.#accessToken?.expiresAt && this.#accessToken.expiresAt.getTime() < Date.now() - 1000 * 60 * 60);
|
|
9519
|
+
}
|
|
9520
|
+
}
|
|
9408
9521
|
// pkgs/@akanjs/cli/application/application.command.ts
|
|
9409
9522
|
import { select as select6 } from "@inquirer/prompts";
|
|
9410
9523
|
|
|
@@ -10238,6 +10351,10 @@ class PackageRunner extends runner("package") {
|
|
|
10238
10351
|
pkg.generateTsconfigJson()
|
|
10239
10352
|
]);
|
|
10240
10353
|
}
|
|
10354
|
+
await this.#copyPackageReadmes(pkg);
|
|
10355
|
+
}
|
|
10356
|
+
async#copyPackageReadmes(pkg) {
|
|
10357
|
+
await Promise.all(["README.md", "README.ko.md"].map((fileName) => pkg.cp(fileName, `${pkg.dist.cwdPath}/${fileName}`)));
|
|
10241
10358
|
}
|
|
10242
10359
|
async updateWorskpaceRootPackageJson(workspace, rootPackageJson) {
|
|
10243
10360
|
const templatePath = "pkgs/@akanjs/cli/templates/workspaceRoot/package.json.template";
|
|
@@ -10310,7 +10427,12 @@ async function getLatestPackageVersion(packageName, tag = "latest", registryUrl)
|
|
|
10310
10427
|
|
|
10311
10428
|
// pkgs/@akanjs/cli/cloud/cloud.runner.ts
|
|
10312
10429
|
class CloudRunner extends runner("cloud") {
|
|
10313
|
-
#akanFrameworkPackages = new Set([
|
|
10430
|
+
#akanFrameworkPackages = new Set([
|
|
10431
|
+
"akanjs",
|
|
10432
|
+
"@akanjs/devkit",
|
|
10433
|
+
"@akanjs/cli",
|
|
10434
|
+
"create-akan-workspace"
|
|
10435
|
+
]);
|
|
10314
10436
|
#getRegistryArgs(registryUrl) {
|
|
10315
10437
|
return registryUrl ? ["--registry", getNpmRegistryUrl(registryUrl)] : [];
|
|
10316
10438
|
}
|
|
@@ -10445,7 +10567,13 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
10445
10567
|
}
|
|
10446
10568
|
await Promise.all(akanPkgs.map(async (library) => {
|
|
10447
10569
|
Logger15.info(`Publishing ${library}@${nextVersion} to ${registry ?? "npm"}...`);
|
|
10448
|
-
await workspace.spawn("npm", [
|
|
10570
|
+
await workspace.spawn("npm", [
|
|
10571
|
+
"publish",
|
|
10572
|
+
"--tag",
|
|
10573
|
+
tag,
|
|
10574
|
+
...this.#getRegistryArgs(registry),
|
|
10575
|
+
...this.#getLocalRegistryAuthArgs(registry)
|
|
10576
|
+
], {
|
|
10449
10577
|
cwd: path38.join(workspace.workspaceRoot, "dist/pkgs", library),
|
|
10450
10578
|
env: this.#getRegistryEnv(registry),
|
|
10451
10579
|
stdio: "inherit"
|
|
@@ -10462,7 +10590,14 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
10462
10590
|
await workspace.spawn("bun", ["update", "-g", "akanjs", "--latest", `--tag=${tag}`, ...registryArgs], { env });
|
|
10463
10591
|
else
|
|
10464
10592
|
await Promise.all([
|
|
10465
|
-
workspace.spawn("bun", [
|
|
10593
|
+
workspace.spawn("bun", [
|
|
10594
|
+
"update",
|
|
10595
|
+
"-g",
|
|
10596
|
+
"akanjs",
|
|
10597
|
+
"--latest",
|
|
10598
|
+
`--tag=${tag}`,
|
|
10599
|
+
...registryArgs
|
|
10600
|
+
], { env }),
|
|
10466
10601
|
this.#updateAkanPkgs(workspace, tag, registry)
|
|
10467
10602
|
]);
|
|
10468
10603
|
}
|
|
@@ -10486,7 +10621,12 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
10486
10621
|
}
|
|
10487
10622
|
#normalizeAkanPackageJson(packageJson, packageName, version) {
|
|
10488
10623
|
const normalized = { ...packageJson, version };
|
|
10489
|
-
for (const field of [
|
|
10624
|
+
for (const field of [
|
|
10625
|
+
"dependencies",
|
|
10626
|
+
"devDependencies",
|
|
10627
|
+
"peerDependencies",
|
|
10628
|
+
"optionalDependencies"
|
|
10629
|
+
]) {
|
|
10490
10630
|
const dependencies = normalized[field];
|
|
10491
10631
|
if (!dependencies)
|
|
10492
10632
|
continue;
|
|
@@ -10497,10 +10637,28 @@ ${chalk7.green("\u27A4")} Authentication Required`));
|
|
|
10497
10637
|
}
|
|
10498
10638
|
return normalized;
|
|
10499
10639
|
}
|
|
10640
|
+
async downloadEnv(workspace) {
|
|
10641
|
+
const repoName = workspace.repoName;
|
|
10642
|
+
const config = await getHostConfig();
|
|
10643
|
+
const self = config.auth ? await getSelf(config.auth.token) : null;
|
|
10644
|
+
if (!self)
|
|
10645
|
+
throw new Error("Not logged in");
|
|
10646
|
+
const res = await fetch(`${akanCloudUrl}/api/akasys/akasys/${repoName}`, {
|
|
10647
|
+
headers: { Authorization: `Bearer ${config.auth?.token}` }
|
|
10648
|
+
});
|
|
10649
|
+
const env = await res.json();
|
|
10650
|
+
Logger15.info(`Downloading environment variables from cloud...`);
|
|
10651
|
+
Logger15.info(`Environment variables: ${JSON.stringify(env.env, null, 2)}`);
|
|
10652
|
+
}
|
|
10653
|
+
async uploadEnv(workspace) {}
|
|
10500
10654
|
}
|
|
10501
10655
|
|
|
10502
10656
|
// pkgs/@akanjs/cli/cloud/cloud.script.ts
|
|
10503
|
-
class CloudScript extends script("cloud", [
|
|
10657
|
+
class CloudScript extends script("cloud", [
|
|
10658
|
+
CloudRunner,
|
|
10659
|
+
ApplicationScript,
|
|
10660
|
+
PackageScript
|
|
10661
|
+
]) {
|
|
10504
10662
|
async login(workspace) {
|
|
10505
10663
|
await this.cloudRunner.login();
|
|
10506
10664
|
}
|
|
@@ -10517,6 +10675,12 @@ class CloudScript extends script("cloud", [CloudRunner, ApplicationScript, Packa
|
|
|
10517
10675
|
const session = new AiSession("general", { workspace, isContinued: true });
|
|
10518
10676
|
await session.ask(question);
|
|
10519
10677
|
}
|
|
10678
|
+
async downloadEnv(workspace) {
|
|
10679
|
+
await this.cloudRunner.downloadEnv(workspace);
|
|
10680
|
+
}
|
|
10681
|
+
async uploadEnv(workspace) {
|
|
10682
|
+
await this.cloudRunner.uploadEnv(workspace);
|
|
10683
|
+
}
|
|
10520
10684
|
async deployAkan(workspace, { test = true, registryUrl } = {}) {
|
|
10521
10685
|
const akanPkgs = await this.cloudRunner.getAkanPkgs(workspace);
|
|
10522
10686
|
await this.packageScript.updateWorskpaceRootPackageJson(workspace);
|
|
@@ -10557,7 +10721,10 @@ class CloudCommand extends command("cloud", [CloudScript], ({ public: target })
|
|
|
10557
10721
|
ask: target({ desc: "Ask AI assistant a question about your project" }).option("question", String, { ask: "question to ask" }).with(Workspace).exec(async function(question, workspace) {
|
|
10558
10722
|
await this.cloudScript.ask(question, workspace);
|
|
10559
10723
|
}),
|
|
10560
|
-
deployAkan: target({
|
|
10724
|
+
deployAkan: target({
|
|
10725
|
+
devOnly: true,
|
|
10726
|
+
desc: "Deploy Akan.js framework to cloud (internal use)"
|
|
10727
|
+
}).option("test", Boolean, { desc: "test the deployment", default: true }).option("registry", String, {
|
|
10561
10728
|
desc: "registry target for publishing Akan packages",
|
|
10562
10729
|
ask: "Select a registry target",
|
|
10563
10730
|
enum: [
|
|
@@ -10582,7 +10749,15 @@ class CloudCommand extends command("cloud", [CloudScript], ({ public: target })
|
|
|
10582
10749
|
{ label: "local", value: "local" }
|
|
10583
10750
|
]
|
|
10584
10751
|
}).exec(async function(workspace, tag, registry) {
|
|
10585
|
-
await this.cloudScript.update(workspace, tag, {
|
|
10752
|
+
await this.cloudScript.update(workspace, tag, {
|
|
10753
|
+
registryUrl: resolveRegistryUrl(registry)
|
|
10754
|
+
});
|
|
10755
|
+
}),
|
|
10756
|
+
downloadEnv: target({ desc: "Download environment variables from cloud" }).with(Workspace).exec(async function(workspace) {
|
|
10757
|
+
await this.cloudScript.downloadEnv(workspace);
|
|
10758
|
+
}),
|
|
10759
|
+
uploadEnv: target({ desc: "Upload environment variables to cloud" }).with(Workspace).exec(async function(workspace) {
|
|
10760
|
+
await this.cloudScript.uploadEnv(workspace);
|
|
10586
10761
|
})
|
|
10587
10762
|
})) {
|
|
10588
10763
|
}
|
|
@@ -10603,7 +10778,7 @@ class GuidelinePrompt extends Prompter {
|
|
|
10603
10778
|
return page;
|
|
10604
10779
|
if (page.endsWith(".tsx"))
|
|
10605
10780
|
return page;
|
|
10606
|
-
return `apps/
|
|
10781
|
+
return `apps/akan/page${page}`;
|
|
10607
10782
|
}
|
|
10608
10783
|
async#getScanFilePaths(matchPattern, { avoidDirs = ["node_modules", ".next"], filterText } = {}) {
|
|
10609
10784
|
const glob = new Bun.Glob(matchPattern);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akanjs/cli",
|
|
3
|
-
"version": "2.1.0",
|
|
3
|
+
"version": "2.1.1-rc.0",
|
|
4
4
|
"sourceType": "module",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -33,8 +33,9 @@
|
|
|
33
33
|
"@langchain/core": "^1.1.47",
|
|
34
34
|
"@langchain/deepseek": "^1.0.26",
|
|
35
35
|
"@langchain/openai": "^1.4.6",
|
|
36
|
+
"@tailwindcss/node": "^4.3.0",
|
|
36
37
|
"@trapezedev/project": "^7.1.4",
|
|
37
|
-
"akanjs": "2.1.0",
|
|
38
|
+
"akanjs": "2.1.1-rc.0",
|
|
38
39
|
"chalk": "^5.6.2",
|
|
39
40
|
"commander": "^14.0.3",
|
|
40
41
|
"daisyui": "^5.5.20",
|