@base44-preview/cli 0.0.14-pr.92.11b6028 → 0.0.14-pr.93.54ecdc1

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.
Files changed (3) hide show
  1. package/README.md +40 -138
  2. package/dist/cli/index.js +1855 -1943
  3. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -17,13 +17,13 @@ import { finished } from "node:stream/promises";
17
17
  import EE, { EventEmitter as EventEmitter$1 } from "events";
18
18
  import fs$2, { access, constants as constants$1, copyFile, mkdir, readFile, unlink, writeFile } from "node:fs/promises";
19
19
  import { Buffer as Buffer$1 } from "buffer";
20
+ import tty from "node:tty";
20
21
  import { randomBytes, randomUUID } from "node:crypto";
21
22
  import { StringDecoder } from "node:string_decoder";
22
23
  import assert from "assert";
23
24
  import * as realZlib$1 from "zlib";
24
25
  import realZlib from "zlib";
25
26
  import assert$1 from "node:assert";
26
- import tty from "node:tty";
27
27
  import { scheduler, setImmediate as setImmediate$1, setTimeout as setTimeout$1 } from "node:timers/promises";
28
28
  import { serialize } from "node:v8";
29
29
  import { Buffer as Buffer$2 } from "node:buffer";
@@ -16737,7 +16737,7 @@ async function readAllEntities(entitiesDir) {
16737
16737
 
16738
16738
  //#endregion
16739
16739
  //#region src/core/resources/entity/api.ts
16740
- async function syncEntities(entities) {
16740
+ async function pushEntities(entities) {
16741
16741
  const appClient = getAppClient();
16742
16742
  const schemaSyncPayload = Object.fromEntries(entities.map((entity) => [entity.name, entity]));
16743
16743
  const response = await appClient.put("entity-schemas", {
@@ -16752,17 +16752,6 @@ async function syncEntities(entities) {
16752
16752
  return SyncEntitiesResponseSchema.parse(await response.json());
16753
16753
  }
16754
16754
 
16755
- //#endregion
16756
- //#region src/core/resources/entity/deploy.ts
16757
- async function pushEntities(entities) {
16758
- if (entities.length === 0) return {
16759
- created: [],
16760
- updated: [],
16761
- deleted: []
16762
- };
16763
- return syncEntities(entities);
16764
- }
16765
-
16766
16755
  //#endregion
16767
16756
  //#region src/core/resources/entity/resource.ts
16768
16757
  const entityResource = {
@@ -16854,11 +16843,6 @@ async function loadFunctionCode(fn) {
16854
16843
  };
16855
16844
  }
16856
16845
  async function pushFunctions(functions) {
16857
- if (functions.length === 0) return {
16858
- deployed: [],
16859
- deleted: [],
16860
- errors: null
16861
- };
16862
16846
  return deployFunctions(await Promise.all(functions.map(loadFunctionCode)));
16863
16847
  }
16864
16848
 
@@ -25566,438 +25550,1421 @@ async function envLocalExists(projectRoot) {
25566
25550
  }
25567
25551
 
25568
25552
  //#endregion
25569
- //#region src/core/site/schema.ts
25553
+ //#region src/core/config.ts
25554
+ const __dirname$1 = dirname(fileURLToPath(import.meta.url));
25555
+ function getBase44GlobalDir() {
25556
+ return join(homedir(), ".base44");
25557
+ }
25558
+ function getAuthFilePath() {
25559
+ return join(getBase44GlobalDir(), "auth", "auth.json");
25560
+ }
25561
+ function getTemplatesDir() {
25562
+ return join(__dirname$1, "templates");
25563
+ }
25564
+ function getTemplatesIndexPath() {
25565
+ return join(getTemplatesDir(), "templates.json");
25566
+ }
25567
+ function getProjectEnvPath(projectRoot) {
25568
+ return join(projectRoot, PROJECT_SUBDIR, ".env.local");
25569
+ }
25570
25570
  /**
25571
- * Response from the deploy API endpoint.
25571
+ * Load .env.local from the project root if it exists.
25572
+ * Values won't override existing process.env variables.
25572
25573
  */
25573
- const DeployResponseSchema = object({ app_url: url() }).transform((data) => ({ appUrl: data.app_url }));
25574
+ async function loadProjectEnv(projectRoot) {
25575
+ const found = projectRoot ? { root: projectRoot } : await findProjectRoot();
25576
+ if (!found) return;
25577
+ (0, import_main.config)({
25578
+ path: getProjectEnvPath(found.root),
25579
+ override: false,
25580
+ quiet: true
25581
+ });
25582
+ }
25583
+ function getBase44ApiUrl() {
25584
+ return process.env.BASE44_API_URL || "https://app.base44.com";
25585
+ }
25586
+ function getBase44ClientId() {
25587
+ return process.env.BASE44_CLIENT_ID;
25588
+ }
25574
25589
 
25575
25590
  //#endregion
25576
- //#region src/core/site/config.ts
25591
+ //#region src/core/clients/oauth-client.ts
25577
25592
  /**
25578
- * Gets all file paths in the output directory.
25579
- * Used to check if the directory contains any files before deployment.
25580
- *
25581
- * @param outputDir - The directory containing built site files
25582
- * @returns Array of relative file paths
25593
+ * HTTP client for OAuth endpoints.
25594
+ * Used only for the login flow (device code, token exchange).
25595
+ * These endpoints don't need Authorization headers - they use client_id + tokens in body.
25583
25596
  */
25584
- async function getSiteFilePaths(outputDir) {
25585
- return await globby("**/*", {
25586
- cwd: outputDir,
25587
- onlyFiles: true,
25588
- absolute: false
25589
- });
25590
- }
25597
+ const oauthClient = distribution_default.create({
25598
+ prefixUrl: getBase44ApiUrl(),
25599
+ headers: { "User-Agent": "Base44 CLI" }
25600
+ });
25591
25601
 
25592
25602
  //#endregion
25593
- //#region src/core/site/api.ts
25603
+ //#region src/core/auth/config.ts
25604
+ const TOKEN_REFRESH_BUFFER_MS = 60 * 1e3;
25605
+ let refreshPromise = null;
25594
25606
  /**
25595
- * Uploads a tar.gz archive file to the Base44 hosting API.
25607
+ * Reads and validates the stored authentication data.
25596
25608
  *
25597
- * @param archivePath - Path to the tar.gz archive file
25598
- * @returns Deploy response with the site URL and deployment details
25599
- * @throws Error if file read or upload fails
25609
+ * @returns The parsed authentication data (tokens, user info).
25610
+ * @throws {Error} If not logged in or if auth data is corrupted.
25611
+ *
25612
+ * @example
25613
+ * const auth = await readAuth();
25614
+ * console.log(`Logged in as: ${auth.email}`);
25600
25615
  */
25601
- async function uploadSite(archivePath) {
25602
- const archiveBuffer = await readFile$1(archivePath);
25603
- const blob = new Blob([archiveBuffer], { type: "application/gzip" });
25604
- const formData = new FormData();
25605
- formData.append("file", blob, "dist.tar.gz");
25606
- const response = await getAppClient().post("deploy-dist", { body: formData });
25607
- return DeployResponseSchema.parse(await response.json());
25616
+ async function readAuth() {
25617
+ try {
25618
+ const parsed = await readJsonFile(getAuthFilePath());
25619
+ const result = AuthDataSchema.safeParse(parsed);
25620
+ if (!result.success) throw new Error(`Invalid authentication data: ${result.error.issues.map((e$1) => e$1.message).join(", ")}`);
25621
+ return result.data;
25622
+ } catch (error) {
25623
+ throw new Error(`Failed to read authentication file: ${error instanceof Error ? error.message : "Unknown error"}`);
25624
+ }
25625
+ }
25626
+ async function writeAuth(authData) {
25627
+ const result = AuthDataSchema.safeParse(authData);
25628
+ if (!result.success) throw new Error(`Invalid authentication data: ${result.error.issues.map((e$1) => e$1.message).join(", ")}`);
25629
+ try {
25630
+ await writeJsonFile(getAuthFilePath(), result.data);
25631
+ } catch (error) {
25632
+ throw new Error(`Failed to write authentication file: ${error instanceof Error ? error.message : "Unknown error"}`);
25633
+ }
25634
+ }
25635
+ async function deleteAuth() {
25636
+ try {
25637
+ await deleteFile(getAuthFilePath());
25638
+ } catch (error) {
25639
+ throw new Error(`Failed to delete authentication file: ${error instanceof Error ? error.message : "Unknown error"}`);
25640
+ }
25641
+ }
25642
+ function isTokenExpired(auth) {
25643
+ return Date.now() >= auth.expiresAt - TOKEN_REFRESH_BUFFER_MS;
25644
+ }
25645
+ async function refreshAndSaveTokens() {
25646
+ if (refreshPromise) return refreshPromise;
25647
+ refreshPromise = (async () => {
25648
+ try {
25649
+ const auth = await readAuth();
25650
+ const tokenResponse = await renewAccessToken(auth.refreshToken);
25651
+ await writeAuth({
25652
+ ...auth,
25653
+ accessToken: tokenResponse.accessToken,
25654
+ refreshToken: tokenResponse.refreshToken,
25655
+ expiresAt: Date.now() + tokenResponse.expiresIn * 1e3
25656
+ });
25657
+ return tokenResponse.accessToken;
25658
+ } catch {
25659
+ await deleteAuth();
25660
+ return null;
25661
+ } finally {
25662
+ refreshPromise = null;
25663
+ }
25664
+ })();
25665
+ return refreshPromise;
25608
25666
  }
25609
-
25610
- //#endregion
25611
- //#region node_modules/minipass/dist/esm/index.js
25612
- const proc = typeof process === "object" && process ? process : {
25613
- stdout: null,
25614
- stderr: null
25615
- };
25616
25667
  /**
25617
- * Return true if the argument is a Minipass stream, Node stream, or something
25618
- * else that Minipass can interact with.
25668
+ * Checks if the user is currently logged in.
25669
+ *
25670
+ * @returns True if authentication data exists and is valid, false otherwise.
25671
+ *
25672
+ * @example
25673
+ * if (await isLoggedIn()) {
25674
+ * console.log("User is logged in");
25675
+ * } else {
25676
+ * console.log("Please login first");
25677
+ * }
25619
25678
  */
25620
- const isStream$1 = (s) => !!s && typeof s === "object" && (s instanceof Minipass || s instanceof Stream || isReadable(s) || isWritable(s));
25679
+ async function isLoggedIn() {
25680
+ try {
25681
+ await readAuth();
25682
+ return true;
25683
+ } catch {
25684
+ return false;
25685
+ }
25686
+ }
25687
+
25688
+ //#endregion
25689
+ //#region src/core/clients/base44-client.ts
25621
25690
  /**
25622
- * Return true if the argument is a valid {@link Minipass.Readable}
25691
+ * Authenticated HTTP client for Base44 API.
25692
+ * Automatically handles token refresh and retry on 401 responses.
25623
25693
  */
25624
- const isReadable = (s) => !!s && typeof s === "object" && s instanceof EventEmitter && typeof s.pipe === "function" && s.pipe !== Stream.Writable.prototype.pipe;
25694
+ const retriedRequests = /* @__PURE__ */ new WeakSet();
25625
25695
  /**
25626
- * Return true if the argument is a valid {@link Minipass.Writable}
25696
+ * Handles 401 responses by refreshing the token and retrying the request.
25697
+ * Only retries once per request to prevent infinite loops.
25627
25698
  */
25628
- const isWritable = (s) => !!s && typeof s === "object" && s instanceof EventEmitter && typeof s.write === "function" && typeof s.end === "function";
25629
- const EOF$1 = Symbol("EOF");
25630
- const MAYBE_EMIT_END = Symbol("maybeEmitEnd");
25631
- const EMITTED_END = Symbol("emittedEnd");
25632
- const EMITTING_END = Symbol("emittingEnd");
25633
- const EMITTED_ERROR = Symbol("emittedError");
25634
- const CLOSED = Symbol("closed");
25635
- const READ$1 = Symbol("read");
25636
- const FLUSH = Symbol("flush");
25637
- const FLUSHCHUNK = Symbol("flushChunk");
25638
- const ENCODING = Symbol("encoding");
25639
- const DECODER = Symbol("decoder");
25640
- const FLOWING = Symbol("flowing");
25641
- const PAUSED = Symbol("paused");
25642
- const RESUME = Symbol("resume");
25643
- const BUFFER$1 = Symbol("buffer");
25644
- const PIPES = Symbol("pipes");
25645
- const BUFFERLENGTH = Symbol("bufferLength");
25646
- const BUFFERPUSH = Symbol("bufferPush");
25647
- const BUFFERSHIFT = Symbol("bufferShift");
25648
- const OBJECTMODE = Symbol("objectMode");
25649
- const DESTROYED = Symbol("destroyed");
25650
- const ERROR = Symbol("error");
25651
- const EMITDATA = Symbol("emitData");
25652
- const EMITEND = Symbol("emitEnd");
25653
- const EMITEND2 = Symbol("emitEnd2");
25654
- const ASYNC = Symbol("async");
25655
- const ABORT = Symbol("abort");
25656
- const ABORTED$1 = Symbol("aborted");
25657
- const SIGNAL = Symbol("signal");
25658
- const DATALISTENERS = Symbol("dataListeners");
25659
- const DISCARDED = Symbol("discarded");
25660
- const defer = (fn) => Promise.resolve().then(fn);
25661
- const nodefer = (fn) => fn();
25662
- const isEndish = (ev) => ev === "end" || ev === "finish" || ev === "prefinish";
25663
- const isArrayBufferLike = (b$2) => b$2 instanceof ArrayBuffer || !!b$2 && typeof b$2 === "object" && b$2.constructor && b$2.constructor.name === "ArrayBuffer" && b$2.byteLength >= 0;
25664
- const isArrayBufferView = (b$2) => !Buffer.isBuffer(b$2) && ArrayBuffer.isView(b$2);
25699
+ async function handleUnauthorized(request, _options, response) {
25700
+ if (response.status !== 401) return;
25701
+ if (retriedRequests.has(request)) return;
25702
+ const newAccessToken = await refreshAndSaveTokens();
25703
+ if (!newAccessToken) return;
25704
+ retriedRequests.add(request);
25705
+ return distribution_default(request, { headers: { Authorization: `Bearer ${newAccessToken}` } });
25706
+ }
25665
25707
  /**
25666
- * Internal class representing a pipe to a destination stream.
25667
- *
25668
- * @internal
25708
+ * Base44 API client with automatic authentication.
25709
+ * Use this for general API calls that require authentication.
25669
25710
  */
25670
- var Pipe = class {
25671
- src;
25672
- dest;
25673
- opts;
25674
- ondrain;
25675
- constructor(src, dest, opts) {
25676
- this.src = src;
25677
- this.dest = dest;
25678
- this.opts = opts;
25679
- this.ondrain = () => src[RESUME]();
25680
- this.dest.on("drain", this.ondrain);
25681
- }
25682
- unpipe() {
25683
- this.dest.removeListener("drain", this.ondrain);
25684
- }
25685
- /* c8 ignore start */
25686
- proxyErrors(_er) {}
25687
- /* c8 ignore stop */
25688
- end() {
25689
- this.unpipe();
25690
- if (this.opts.end) this.dest.end();
25711
+ const base44Client = distribution_default.create({
25712
+ prefixUrl: getBase44ApiUrl(),
25713
+ headers: { "User-Agent": "Base44 CLI" },
25714
+ hooks: {
25715
+ beforeRequest: [async (request) => {
25716
+ try {
25717
+ const auth = await readAuth();
25718
+ if (isTokenExpired(auth)) {
25719
+ const newAccessToken = await refreshAndSaveTokens();
25720
+ if (newAccessToken) {
25721
+ request.headers.set("Authorization", `Bearer ${newAccessToken}`);
25722
+ return;
25723
+ }
25724
+ }
25725
+ request.headers.set("Authorization", `Bearer ${auth.accessToken}`);
25726
+ } catch {}
25727
+ }],
25728
+ afterResponse: [handleUnauthorized]
25691
25729
  }
25692
- };
25730
+ });
25693
25731
  /**
25694
- * Internal class representing a pipe to a destination stream where
25695
- * errors are proxied.
25732
+ * Returns an HTTP client scoped to the current app.
25733
+ * Use this for API calls to app-specific endpoints (entities, functions, etc.).
25696
25734
  *
25697
- * @internal
25735
+ * @throws {Error} If BASE44_CLIENT_ID environment variable is not set.
25736
+ *
25737
+ * @example
25738
+ * const appClient = getAppClient();
25739
+ * const response = await appClient.get("entities");
25698
25740
  */
25699
- var PipeProxyErrors = class extends Pipe {
25700
- unpipe() {
25701
- this.src.removeListener("error", this.proxyErrors);
25702
- super.unpipe();
25741
+ function getAppClient() {
25742
+ const clientId = getBase44ClientId();
25743
+ if (!clientId) throw new Error("BASE44_CLIENT_ID environment variable is required. Set it in your .env.local file.");
25744
+ return base44Client.extend({ prefixUrl: new URL(`/api/apps/${clientId}/`, getBase44ApiUrl()).href });
25745
+ }
25746
+
25747
+ //#endregion
25748
+ //#region src/core/auth/api.ts
25749
+ async function generateDeviceCode() {
25750
+ const response = await oauthClient.post("oauth/device/code", {
25751
+ json: {
25752
+ client_id: AUTH_CLIENT_ID,
25753
+ scope: "apps:read apps:write"
25754
+ },
25755
+ throwHttpErrors: false
25756
+ });
25757
+ if (!response.ok) throw new AuthApiError(`Failed to generate device code: ${response.status} ${response.statusText}`);
25758
+ const result = DeviceCodeResponseSchema.safeParse(await response.json());
25759
+ if (!result.success) throw new AuthValidationError(`Invalid device code response from server: ${result.error.message}`);
25760
+ return result.data;
25761
+ }
25762
+ async function getTokenFromDeviceCode(deviceCode) {
25763
+ const searchParams = new URLSearchParams();
25764
+ searchParams.set("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
25765
+ searchParams.set("device_code", deviceCode);
25766
+ searchParams.set("client_id", AUTH_CLIENT_ID);
25767
+ const response = await oauthClient.post("oauth/token", {
25768
+ body: searchParams.toString(),
25769
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
25770
+ throwHttpErrors: false
25771
+ });
25772
+ const json = await response.json();
25773
+ if (!response.ok) {
25774
+ const errorResult = OAuthErrorSchema.safeParse(json);
25775
+ if (!errorResult.success) throw new AuthValidationError(`Token request failed: ${errorResult.error.message}`);
25776
+ const { error, error_description } = errorResult.data;
25777
+ if (error === "authorization_pending" || error === "slow_down") return null;
25778
+ throw new AuthApiError(error_description ?? `OAuth error: ${error}`);
25703
25779
  }
25704
- constructor(src, dest, opts) {
25705
- super(src, dest, opts);
25706
- this.proxyErrors = (er) => dest.emit("error", er);
25707
- src.on("error", this.proxyErrors);
25780
+ const result = TokenResponseSchema.safeParse(json);
25781
+ if (!result.success) throw new AuthValidationError(`Invalid token response from server: ${result.error.message}`);
25782
+ return result.data;
25783
+ }
25784
+ async function renewAccessToken(refreshToken) {
25785
+ const searchParams = new URLSearchParams();
25786
+ searchParams.set("grant_type", "refresh_token");
25787
+ searchParams.set("refresh_token", refreshToken);
25788
+ searchParams.set("client_id", AUTH_CLIENT_ID);
25789
+ const response = await oauthClient.post("oauth/token", {
25790
+ body: searchParams.toString(),
25791
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
25792
+ throwHttpErrors: false
25793
+ });
25794
+ const json = await response.json();
25795
+ if (!response.ok) {
25796
+ const errorResult = OAuthErrorSchema.safeParse(json);
25797
+ if (!errorResult.success) throw new AuthApiError(`Token refresh failed: ${response.statusText}`);
25798
+ const { error, error_description } = errorResult.data;
25799
+ throw new AuthApiError(error_description ?? `OAuth error: ${error}`);
25800
+ }
25801
+ const result = TokenResponseSchema.safeParse(json);
25802
+ if (!result.success) throw new AuthValidationError(`Invalid token response from server: ${result.error.message}`);
25803
+ return result.data;
25804
+ }
25805
+ async function getUserInfo(accessToken) {
25806
+ const response = await oauthClient.get("oauth/userinfo", { headers: { Authorization: `Bearer ${accessToken}` } });
25807
+ if (!response.ok) throw new AuthApiError(`Failed to fetch user info: ${response.status}`);
25808
+ const result = UserInfoSchema.safeParse(await response.json());
25809
+ if (!result.success) throw new AuthValidationError(`Invalid UserInfo response from server: ${result.error.message}`);
25810
+ return result.data;
25811
+ }
25812
+
25813
+ //#endregion
25814
+ //#region node_modules/chalk/source/vendor/ansi-styles/index.js
25815
+ const ANSI_BACKGROUND_OFFSET = 10;
25816
+ const wrapAnsi16 = (offset = 0) => (code$1) => `\u001B[${code$1 + offset}m`;
25817
+ const wrapAnsi256 = (offset = 0) => (code$1) => `\u001B[${38 + offset};5;${code$1}m`;
25818
+ const wrapAnsi16m = (offset = 0) => (red$1, green$1, blue$1) => `\u001B[${38 + offset};2;${red$1};${green$1};${blue$1}m`;
25819
+ const styles$1 = {
25820
+ modifier: {
25821
+ reset: [0, 0],
25822
+ bold: [1, 22],
25823
+ dim: [2, 22],
25824
+ italic: [3, 23],
25825
+ underline: [4, 24],
25826
+ overline: [53, 55],
25827
+ inverse: [7, 27],
25828
+ hidden: [8, 28],
25829
+ strikethrough: [9, 29]
25830
+ },
25831
+ color: {
25832
+ black: [30, 39],
25833
+ red: [31, 39],
25834
+ green: [32, 39],
25835
+ yellow: [33, 39],
25836
+ blue: [34, 39],
25837
+ magenta: [35, 39],
25838
+ cyan: [36, 39],
25839
+ white: [37, 39],
25840
+ blackBright: [90, 39],
25841
+ gray: [90, 39],
25842
+ grey: [90, 39],
25843
+ redBright: [91, 39],
25844
+ greenBright: [92, 39],
25845
+ yellowBright: [93, 39],
25846
+ blueBright: [94, 39],
25847
+ magentaBright: [95, 39],
25848
+ cyanBright: [96, 39],
25849
+ whiteBright: [97, 39]
25850
+ },
25851
+ bgColor: {
25852
+ bgBlack: [40, 49],
25853
+ bgRed: [41, 49],
25854
+ bgGreen: [42, 49],
25855
+ bgYellow: [43, 49],
25856
+ bgBlue: [44, 49],
25857
+ bgMagenta: [45, 49],
25858
+ bgCyan: [46, 49],
25859
+ bgWhite: [47, 49],
25860
+ bgBlackBright: [100, 49],
25861
+ bgGray: [100, 49],
25862
+ bgGrey: [100, 49],
25863
+ bgRedBright: [101, 49],
25864
+ bgGreenBright: [102, 49],
25865
+ bgYellowBright: [103, 49],
25866
+ bgBlueBright: [104, 49],
25867
+ bgMagentaBright: [105, 49],
25868
+ bgCyanBright: [106, 49],
25869
+ bgWhiteBright: [107, 49]
25708
25870
  }
25709
25871
  };
25710
- const isObjectModeOptions = (o$2) => !!o$2.objectMode;
25711
- const isEncodingOptions = (o$2) => !o$2.objectMode && !!o$2.encoding && o$2.encoding !== "buffer";
25712
- /**
25713
- * Main export, the Minipass class
25714
- *
25715
- * `RType` is the type of data emitted, defaults to Buffer
25716
- *
25717
- * `WType` is the type of data to be written, if RType is buffer or string,
25718
- * then any {@link Minipass.ContiguousData} is allowed.
25719
- *
25720
- * `Events` is the set of event handler signatures that this object
25721
- * will emit, see {@link Minipass.Events}
25722
- */
25723
- var Minipass = class extends EventEmitter {
25724
- [FLOWING] = false;
25725
- [PAUSED] = false;
25726
- [PIPES] = [];
25727
- [BUFFER$1] = [];
25728
- [OBJECTMODE];
25729
- [ENCODING];
25730
- [ASYNC];
25731
- [DECODER];
25732
- [EOF$1] = false;
25733
- [EMITTED_END] = false;
25734
- [EMITTING_END] = false;
25735
- [CLOSED] = false;
25736
- [EMITTED_ERROR] = null;
25737
- [BUFFERLENGTH] = 0;
25738
- [DESTROYED] = false;
25739
- [SIGNAL];
25740
- [ABORTED$1] = false;
25741
- [DATALISTENERS] = 0;
25742
- [DISCARDED] = false;
25743
- /**
25744
- * true if the stream can be written
25745
- */
25746
- writable = true;
25747
- /**
25748
- * true if the stream can be read
25749
- */
25750
- readable = true;
25751
- /**
25752
- * If `RType` is Buffer, then options do not need to be provided.
25753
- * Otherwise, an options object must be provided to specify either
25754
- * {@link Minipass.SharedOptions.objectMode} or
25755
- * {@link Minipass.SharedOptions.encoding}, as appropriate.
25756
- */
25757
- constructor(...args) {
25758
- const options = args[0] || {};
25759
- super();
25760
- if (options.objectMode && typeof options.encoding === "string") throw new TypeError("Encoding and objectMode may not be used together");
25761
- if (isObjectModeOptions(options)) {
25762
- this[OBJECTMODE] = true;
25763
- this[ENCODING] = null;
25764
- } else if (isEncodingOptions(options)) {
25765
- this[ENCODING] = options.encoding;
25766
- this[OBJECTMODE] = false;
25767
- } else {
25768
- this[OBJECTMODE] = false;
25769
- this[ENCODING] = null;
25770
- }
25771
- this[ASYNC] = !!options.async;
25772
- this[DECODER] = this[ENCODING] ? new StringDecoder(this[ENCODING]) : null;
25773
- if (options && options.debugExposeBuffer === true) Object.defineProperty(this, "buffer", { get: () => this[BUFFER$1] });
25774
- if (options && options.debugExposePipes === true) Object.defineProperty(this, "pipes", { get: () => this[PIPES] });
25775
- const { signal } = options;
25776
- if (signal) {
25777
- this[SIGNAL] = signal;
25778
- if (signal.aborted) this[ABORT]();
25779
- else signal.addEventListener("abort", () => this[ABORT]());
25872
+ const modifierNames = Object.keys(styles$1.modifier);
25873
+ const foregroundColorNames = Object.keys(styles$1.color);
25874
+ const backgroundColorNames = Object.keys(styles$1.bgColor);
25875
+ const colorNames = [...foregroundColorNames, ...backgroundColorNames];
25876
+ function assembleStyles() {
25877
+ const codes = /* @__PURE__ */ new Map();
25878
+ for (const [groupName, group] of Object.entries(styles$1)) {
25879
+ for (const [styleName, style] of Object.entries(group)) {
25880
+ styles$1[styleName] = {
25881
+ open: `\u001B[${style[0]}m`,
25882
+ close: `\u001B[${style[1]}m`
25883
+ };
25884
+ group[styleName] = styles$1[styleName];
25885
+ codes.set(style[0], style[1]);
25780
25886
  }
25887
+ Object.defineProperty(styles$1, groupName, {
25888
+ value: group,
25889
+ enumerable: false
25890
+ });
25781
25891
  }
25782
- /**
25783
- * The amount of data stored in the buffer waiting to be read.
25784
- *
25785
- * For Buffer strings, this will be the total byte length.
25786
- * For string encoding streams, this will be the string character length,
25787
- * according to JavaScript's `string.length` logic.
25788
- * For objectMode streams, this is a count of the items waiting to be
25789
- * emitted.
25790
- */
25791
- get bufferLength() {
25792
- return this[BUFFERLENGTH];
25892
+ Object.defineProperty(styles$1, "codes", {
25893
+ value: codes,
25894
+ enumerable: false
25895
+ });
25896
+ styles$1.color.close = "\x1B[39m";
25897
+ styles$1.bgColor.close = "\x1B[49m";
25898
+ styles$1.color.ansi = wrapAnsi16();
25899
+ styles$1.color.ansi256 = wrapAnsi256();
25900
+ styles$1.color.ansi16m = wrapAnsi16m();
25901
+ styles$1.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
25902
+ styles$1.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
25903
+ styles$1.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
25904
+ Object.defineProperties(styles$1, {
25905
+ rgbToAnsi256: {
25906
+ value(red$1, green$1, blue$1) {
25907
+ if (red$1 === green$1 && green$1 === blue$1) {
25908
+ if (red$1 < 8) return 16;
25909
+ if (red$1 > 248) return 231;
25910
+ return Math.round((red$1 - 8) / 247 * 24) + 232;
25911
+ }
25912
+ return 16 + 36 * Math.round(red$1 / 255 * 5) + 6 * Math.round(green$1 / 255 * 5) + Math.round(blue$1 / 255 * 5);
25913
+ },
25914
+ enumerable: false
25915
+ },
25916
+ hexToRgb: {
25917
+ value(hex) {
25918
+ const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
25919
+ if (!matches) return [
25920
+ 0,
25921
+ 0,
25922
+ 0
25923
+ ];
25924
+ let [colorString] = matches;
25925
+ if (colorString.length === 3) colorString = [...colorString].map((character) => character + character).join("");
25926
+ const integer$1 = Number.parseInt(colorString, 16);
25927
+ return [
25928
+ integer$1 >> 16 & 255,
25929
+ integer$1 >> 8 & 255,
25930
+ integer$1 & 255
25931
+ ];
25932
+ },
25933
+ enumerable: false
25934
+ },
25935
+ hexToAnsi256: {
25936
+ value: (hex) => styles$1.rgbToAnsi256(...styles$1.hexToRgb(hex)),
25937
+ enumerable: false
25938
+ },
25939
+ ansi256ToAnsi: {
25940
+ value(code$1) {
25941
+ if (code$1 < 8) return 30 + code$1;
25942
+ if (code$1 < 16) return 90 + (code$1 - 8);
25943
+ let red$1;
25944
+ let green$1;
25945
+ let blue$1;
25946
+ if (code$1 >= 232) {
25947
+ red$1 = ((code$1 - 232) * 10 + 8) / 255;
25948
+ green$1 = red$1;
25949
+ blue$1 = red$1;
25950
+ } else {
25951
+ code$1 -= 16;
25952
+ const remainder = code$1 % 36;
25953
+ red$1 = Math.floor(code$1 / 36) / 5;
25954
+ green$1 = Math.floor(remainder / 6) / 5;
25955
+ blue$1 = remainder % 6 / 5;
25956
+ }
25957
+ const value = Math.max(red$1, green$1, blue$1) * 2;
25958
+ if (value === 0) return 30;
25959
+ let result = 30 + (Math.round(blue$1) << 2 | Math.round(green$1) << 1 | Math.round(red$1));
25960
+ if (value === 2) result += 60;
25961
+ return result;
25962
+ },
25963
+ enumerable: false
25964
+ },
25965
+ rgbToAnsi: {
25966
+ value: (red$1, green$1, blue$1) => styles$1.ansi256ToAnsi(styles$1.rgbToAnsi256(red$1, green$1, blue$1)),
25967
+ enumerable: false
25968
+ },
25969
+ hexToAnsi: {
25970
+ value: (hex) => styles$1.ansi256ToAnsi(styles$1.hexToAnsi256(hex)),
25971
+ enumerable: false
25972
+ }
25973
+ });
25974
+ return styles$1;
25975
+ }
25976
+ const ansiStyles = assembleStyles();
25977
+ var ansi_styles_default = ansiStyles;
25978
+
25979
+ //#endregion
25980
+ //#region node_modules/chalk/source/vendor/supports-color/index.js
25981
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) {
25982
+ const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
25983
+ const position = argv.indexOf(prefix + flag);
25984
+ const terminatorPosition = argv.indexOf("--");
25985
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
25986
+ }
25987
+ const { env } = process$1;
25988
+ let flagForceColor;
25989
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) flagForceColor = 0;
25990
+ else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) flagForceColor = 1;
25991
+ function envForceColor() {
25992
+ if ("FORCE_COLOR" in env) {
25993
+ if (env.FORCE_COLOR === "true") return 1;
25994
+ if (env.FORCE_COLOR === "false") return 0;
25995
+ return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
25793
25996
  }
25794
- /**
25795
- * The `BufferEncoding` currently in use, or `null`
25796
- */
25797
- get encoding() {
25798
- return this[ENCODING];
25997
+ }
25998
+ function translateLevel(level) {
25999
+ if (level === 0) return false;
26000
+ return {
26001
+ level,
26002
+ hasBasic: true,
26003
+ has256: level >= 2,
26004
+ has16m: level >= 3
26005
+ };
26006
+ }
26007
+ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
26008
+ const noFlagForceColor = envForceColor();
26009
+ if (noFlagForceColor !== void 0) flagForceColor = noFlagForceColor;
26010
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
26011
+ if (forceColor === 0) return 0;
26012
+ if (sniffFlags) {
26013
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) return 3;
26014
+ if (hasFlag("color=256")) return 2;
25799
26015
  }
25800
- /**
25801
- * @deprecated - This is a read only property
25802
- */
25803
- set encoding(_enc) {
25804
- throw new Error("Encoding must be set at instantiation time");
26016
+ if ("TF_BUILD" in env && "AGENT_NAME" in env) return 1;
26017
+ if (haveStream && !streamIsTTY && forceColor === void 0) return 0;
26018
+ const min = forceColor || 0;
26019
+ if (env.TERM === "dumb") return min;
26020
+ if (process$1.platform === "win32") {
26021
+ const osRelease = os.release().split(".");
26022
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
26023
+ return 1;
25805
26024
  }
25806
- /**
25807
- * @deprecated - Encoding may only be set at instantiation time
25808
- */
25809
- setEncoding(_enc) {
25810
- throw new Error("Encoding must be set at instantiation time");
26025
+ if ("CI" in env) {
26026
+ if ([
26027
+ "GITHUB_ACTIONS",
26028
+ "GITEA_ACTIONS",
26029
+ "CIRCLECI"
26030
+ ].some((key) => key in env)) return 3;
26031
+ if ([
26032
+ "TRAVIS",
26033
+ "APPVEYOR",
26034
+ "GITLAB_CI",
26035
+ "BUILDKITE",
26036
+ "DRONE"
26037
+ ].some((sign) => sign in env) || env.CI_NAME === "codeship") return 1;
26038
+ return min;
25811
26039
  }
25812
- /**
25813
- * True if this is an objectMode stream
25814
- */
25815
- get objectMode() {
25816
- return this[OBJECTMODE];
26040
+ if ("TEAMCITY_VERSION" in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
26041
+ if (env.COLORTERM === "truecolor") return 3;
26042
+ if (env.TERM === "xterm-kitty") return 3;
26043
+ if (env.TERM === "xterm-ghostty") return 3;
26044
+ if (env.TERM === "wezterm") return 3;
26045
+ if ("TERM_PROGRAM" in env) {
26046
+ const version$2 = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
26047
+ switch (env.TERM_PROGRAM) {
26048
+ case "iTerm.app": return version$2 >= 3 ? 3 : 2;
26049
+ case "Apple_Terminal": return 2;
26050
+ }
25817
26051
  }
25818
- /**
25819
- * @deprecated - This is a read-only property
25820
- */
25821
- set objectMode(_om) {
25822
- throw new Error("objectMode must be set at instantiation time");
26052
+ if (/-256(color)?$/i.test(env.TERM)) return 2;
26053
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) return 1;
26054
+ if ("COLORTERM" in env) return 1;
26055
+ return min;
26056
+ }
26057
+ function createSupportsColor(stream, options = {}) {
26058
+ return translateLevel(_supportsColor(stream, {
26059
+ streamIsTTY: stream && stream.isTTY,
26060
+ ...options
26061
+ }));
26062
+ }
26063
+ const supportsColor = {
26064
+ stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
26065
+ stderr: createSupportsColor({ isTTY: tty.isatty(2) })
26066
+ };
26067
+ var supports_color_default = supportsColor;
26068
+
26069
+ //#endregion
26070
+ //#region node_modules/chalk/source/utilities.js
26071
+ function stringReplaceAll(string$2, substring, replacer) {
26072
+ let index = string$2.indexOf(substring);
26073
+ if (index === -1) return string$2;
26074
+ const substringLength = substring.length;
26075
+ let endIndex = 0;
26076
+ let returnValue = "";
26077
+ do {
26078
+ returnValue += string$2.slice(endIndex, index) + substring + replacer;
26079
+ endIndex = index + substringLength;
26080
+ index = string$2.indexOf(substring, endIndex);
26081
+ } while (index !== -1);
26082
+ returnValue += string$2.slice(endIndex);
26083
+ return returnValue;
26084
+ }
26085
+ function stringEncaseCRLFWithFirstIndex(string$2, prefix, postfix, index) {
26086
+ let endIndex = 0;
26087
+ let returnValue = "";
26088
+ do {
26089
+ const gotCR = string$2[index - 1] === "\r";
26090
+ returnValue += string$2.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
26091
+ endIndex = index + 1;
26092
+ index = string$2.indexOf("\n", endIndex);
26093
+ } while (index !== -1);
26094
+ returnValue += string$2.slice(endIndex);
26095
+ return returnValue;
26096
+ }
26097
+
26098
+ //#endregion
26099
+ //#region node_modules/chalk/source/index.js
26100
+ const { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
26101
+ const GENERATOR = Symbol("GENERATOR");
26102
+ const STYLER = Symbol("STYLER");
26103
+ const IS_EMPTY = Symbol("IS_EMPTY");
26104
+ const levelMapping = [
26105
+ "ansi",
26106
+ "ansi",
26107
+ "ansi256",
26108
+ "ansi16m"
26109
+ ];
26110
+ const styles = Object.create(null);
26111
+ const applyOptions = (object$1, options = {}) => {
26112
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) throw new Error("The `level` option should be an integer from 0 to 3");
26113
+ const colorLevel = stdoutColor ? stdoutColor.level : 0;
26114
+ object$1.level = options.level === void 0 ? colorLevel : options.level;
26115
+ };
26116
+ const chalkFactory = (options) => {
26117
+ const chalk$1 = (...strings) => strings.join(" ");
26118
+ applyOptions(chalk$1, options);
26119
+ Object.setPrototypeOf(chalk$1, createChalk.prototype);
26120
+ return chalk$1;
26121
+ };
26122
+ function createChalk(options) {
26123
+ return chalkFactory(options);
26124
+ }
26125
+ Object.setPrototypeOf(createChalk.prototype, Function.prototype);
26126
+ for (const [styleName, style] of Object.entries(ansi_styles_default)) styles[styleName] = { get() {
26127
+ const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
26128
+ Object.defineProperty(this, styleName, { value: builder });
26129
+ return builder;
26130
+ } };
26131
+ styles.visible = { get() {
26132
+ const builder = createBuilder(this, this[STYLER], true);
26133
+ Object.defineProperty(this, "visible", { value: builder });
26134
+ return builder;
26135
+ } };
26136
+ const getModelAnsi = (model, level, type, ...arguments_) => {
26137
+ if (model === "rgb") {
26138
+ if (level === "ansi16m") return ansi_styles_default[type].ansi16m(...arguments_);
26139
+ if (level === "ansi256") return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
26140
+ return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
25823
26141
  }
25824
- /**
25825
- * true if this is an async stream
25826
- */
25827
- get ["async"]() {
25828
- return this[ASYNC];
26142
+ if (model === "hex") return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
26143
+ return ansi_styles_default[type][model](...arguments_);
26144
+ };
26145
+ for (const model of [
26146
+ "rgb",
26147
+ "hex",
26148
+ "ansi256"
26149
+ ]) {
26150
+ styles[model] = { get() {
26151
+ const { level } = this;
26152
+ return function(...arguments_) {
26153
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
26154
+ return createBuilder(this, styler, this[IS_EMPTY]);
26155
+ };
26156
+ } };
26157
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
26158
+ styles[bgModel] = { get() {
26159
+ const { level } = this;
26160
+ return function(...arguments_) {
26161
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
26162
+ return createBuilder(this, styler, this[IS_EMPTY]);
26163
+ };
26164
+ } };
26165
+ }
26166
+ const proto = Object.defineProperties(() => {}, {
26167
+ ...styles,
26168
+ level: {
26169
+ enumerable: true,
26170
+ get() {
26171
+ return this[GENERATOR].level;
26172
+ },
26173
+ set(level) {
26174
+ this[GENERATOR].level = level;
26175
+ }
25829
26176
  }
25830
- /**
25831
- * Set to true to make this stream async.
25832
- *
25833
- * Once set, it cannot be unset, as this would potentially cause incorrect
25834
- * behavior. Ie, a sync stream can be made async, but an async stream
25835
- * cannot be safely made sync.
25836
- */
25837
- set ["async"](a$1) {
25838
- this[ASYNC] = this[ASYNC] || !!a$1;
26177
+ });
26178
+ const createStyler = (open$1, close, parent) => {
26179
+ let openAll;
26180
+ let closeAll;
26181
+ if (parent === void 0) {
26182
+ openAll = open$1;
26183
+ closeAll = close;
26184
+ } else {
26185
+ openAll = parent.openAll + open$1;
26186
+ closeAll = close + parent.closeAll;
25839
26187
  }
25840
- [ABORT]() {
25841
- this[ABORTED$1] = true;
25842
- this.emit("abort", this[SIGNAL]?.reason);
25843
- this.destroy(this[SIGNAL]?.reason);
26188
+ return {
26189
+ open: open$1,
26190
+ close,
26191
+ openAll,
26192
+ closeAll,
26193
+ parent
26194
+ };
26195
+ };
26196
+ const createBuilder = (self$1, _styler, _isEmpty) => {
26197
+ const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
26198
+ Object.setPrototypeOf(builder, proto);
26199
+ builder[GENERATOR] = self$1;
26200
+ builder[STYLER] = _styler;
26201
+ builder[IS_EMPTY] = _isEmpty;
26202
+ return builder;
26203
+ };
26204
+ const applyStyle = (self$1, string$2) => {
26205
+ if (self$1.level <= 0 || !string$2) return self$1[IS_EMPTY] ? "" : string$2;
26206
+ let styler = self$1[STYLER];
26207
+ if (styler === void 0) return string$2;
26208
+ const { openAll, closeAll } = styler;
26209
+ if (string$2.includes("\x1B")) while (styler !== void 0) {
26210
+ string$2 = stringReplaceAll(string$2, styler.close, styler.open);
26211
+ styler = styler.parent;
25844
26212
  }
25845
- /**
25846
- * True if the stream has been aborted.
25847
- */
25848
- get aborted() {
25849
- return this[ABORTED$1];
26213
+ const lfIndex = string$2.indexOf("\n");
26214
+ if (lfIndex !== -1) string$2 = stringEncaseCRLFWithFirstIndex(string$2, closeAll, openAll, lfIndex);
26215
+ return openAll + string$2 + closeAll;
26216
+ };
26217
+ Object.defineProperties(createChalk.prototype, styles);
26218
+ const chalk = createChalk();
26219
+ const chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
26220
+ var source_default = chalk;
26221
+
26222
+ //#endregion
26223
+ //#region src/cli/utils/theme.ts
26224
+ /**
26225
+ * Base44 CLI theme configuration
26226
+ */
26227
+ const theme = {
26228
+ colors: {
26229
+ base44Orange: source_default.hex("#E86B3C"),
26230
+ base44OrangeBackground: source_default.bgHex("#E86B3C"),
26231
+ shinyOrange: source_default.hex("#FFD700"),
26232
+ links: source_default.hex("#00D4FF"),
26233
+ white: source_default.white
26234
+ },
26235
+ styles: {
26236
+ header: source_default.dim,
26237
+ bold: source_default.bold,
26238
+ dim: source_default.dim
25850
26239
  }
25851
- /**
25852
- * No-op setter. Stream aborted status is set via the AbortSignal provided
25853
- * in the constructor options.
25854
- */
25855
- set aborted(_$2) {}
25856
- write(chunk, encoding, cb) {
25857
- if (this[ABORTED$1]) return false;
25858
- if (this[EOF$1]) throw new Error("write after end");
25859
- if (this[DESTROYED]) {
25860
- this.emit("error", Object.assign(/* @__PURE__ */ new Error("Cannot call write after a stream was destroyed"), { code: "ERR_STREAM_DESTROYED" }));
25861
- return true;
25862
- }
25863
- if (typeof encoding === "function") {
25864
- cb = encoding;
25865
- encoding = "utf8";
25866
- }
25867
- if (!encoding) encoding = "utf8";
25868
- const fn = this[ASYNC] ? defer : nodefer;
25869
- if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
25870
- if (isArrayBufferView(chunk)) chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
25871
- else if (isArrayBufferLike(chunk)) chunk = Buffer.from(chunk);
25872
- else if (typeof chunk !== "string") throw new Error("Non-contiguous data written to non-objectMode stream");
25873
- }
25874
- if (this[OBJECTMODE]) {
25875
- /* c8 ignore start */
25876
- if (this[FLOWING] && this[BUFFERLENGTH] !== 0) this[FLUSH](true);
25877
- /* c8 ignore stop */
25878
- if (this[FLOWING]) this.emit("data", chunk);
25879
- else this[BUFFERPUSH](chunk);
25880
- if (this[BUFFERLENGTH] !== 0) this.emit("readable");
25881
- if (cb) fn(cb);
25882
- return this[FLOWING];
25883
- }
25884
- if (!chunk.length) {
25885
- if (this[BUFFERLENGTH] !== 0) this.emit("readable");
25886
- if (cb) fn(cb);
25887
- return this[FLOWING];
25888
- }
25889
- if (typeof chunk === "string" && !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) chunk = Buffer.from(chunk, encoding);
25890
- if (Buffer.isBuffer(chunk) && this[ENCODING]) chunk = this[DECODER].write(chunk);
25891
- if (this[FLOWING] && this[BUFFERLENGTH] !== 0) this[FLUSH](true);
25892
- if (this[FLOWING]) this.emit("data", chunk);
25893
- else this[BUFFERPUSH](chunk);
25894
- if (this[BUFFERLENGTH] !== 0) this.emit("readable");
25895
- if (cb) fn(cb);
25896
- return this[FLOWING];
26240
+ };
26241
+
26242
+ //#endregion
26243
+ //#region src/cli/utils/animate.ts
26244
+ /**
26245
+ * Sleep for a specified number of milliseconds.
26246
+ */
26247
+ function sleep(ms) {
26248
+ return new Promise((resolve$1) => setTimeout(resolve$1, ms));
26249
+ }
26250
+ /**
26251
+ * Animate a single line with a left-to-right color reveal.
26252
+ */
26253
+ async function animateLineReveal(line, duration$2) {
26254
+ const steps = 8;
26255
+ const stepDuration = duration$2 / steps;
26256
+ for (let step = 0; step <= steps; step++) {
26257
+ const progress = step / steps;
26258
+ const revealIndex = Math.floor(progress * line.length);
26259
+ let output = "";
26260
+ for (let i$1 = 0; i$1 < line.length; i$1++) if (i$1 < revealIndex) output += theme.colors.base44Orange(line[i$1]);
26261
+ else if (i$1 === revealIndex) output += theme.colors.shinyOrange(line[i$1]);
26262
+ else output += theme.styles.dim(line[i$1]);
26263
+ process.stdout.write(`\r${output}`);
26264
+ await sleep(stepDuration);
25897
26265
  }
25898
- /**
25899
- * Low-level explicit read method.
25900
- *
25901
- * In objectMode, the argument is ignored, and one item is returned if
25902
- * available.
25903
- *
25904
- * `n` is the number of bytes (or in the case of encoding streams,
25905
- * characters) to consume. If `n` is not provided, then the entire buffer
25906
- * is returned, or `null` is returned if no data is available.
25907
- *
25908
- * If `n` is greater that the amount of data in the internal buffer,
25909
- * then `null` is returned.
25910
- */
25911
- read(n$1) {
25912
- if (this[DESTROYED]) return null;
25913
- this[DISCARDED] = false;
25914
- if (this[BUFFERLENGTH] === 0 || n$1 === 0 || n$1 && n$1 > this[BUFFERLENGTH]) {
25915
- this[MAYBE_EMIT_END]();
25916
- return null;
26266
+ process.stdout.write(`\r${theme.colors.base44Orange(line)}\n`);
26267
+ }
26268
+ /**
26269
+ * Quick shimmer pass over the entire banner.
26270
+ */
26271
+ async function shimmerPass(lines, duration$2) {
26272
+ const moveUp = `\x1b[${lines.length}A`;
26273
+ const steps = 12;
26274
+ const stepDuration = duration$2 / steps;
26275
+ const maxWidth = Math.max(...lines.map((l$1) => l$1.length));
26276
+ for (let step = 0; step <= steps; step++) {
26277
+ const shimmerPos = Math.floor(step / steps * (maxWidth + 6));
26278
+ process.stdout.write(moveUp);
26279
+ for (const line of lines) {
26280
+ let output = "";
26281
+ for (let i$1 = 0; i$1 < line.length; i$1++) {
26282
+ const dist = Math.abs(i$1 - shimmerPos);
26283
+ if (dist < 3) output += dist === 0 ? theme.colors.white(line[i$1]) : theme.colors.shinyOrange(line[i$1]);
26284
+ else output += theme.colors.base44Orange(line[i$1]);
26285
+ }
26286
+ console.log(output);
25917
26287
  }
25918
- if (this[OBJECTMODE]) n$1 = null;
25919
- if (this[BUFFER$1].length > 1 && !this[OBJECTMODE]) this[BUFFER$1] = [this[ENCODING] ? this[BUFFER$1].join("") : Buffer.concat(this[BUFFER$1], this[BUFFERLENGTH])];
25920
- const ret = this[READ$1](n$1 || null, this[BUFFER$1][0]);
25921
- this[MAYBE_EMIT_END]();
25922
- return ret;
26288
+ await sleep(stepDuration);
25923
26289
  }
25924
- [READ$1](n$1, chunk) {
25925
- if (this[OBJECTMODE]) this[BUFFERSHIFT]();
25926
- else {
25927
- const c$1 = chunk;
25928
- if (n$1 === c$1.length || n$1 === null) this[BUFFERSHIFT]();
25929
- else if (typeof c$1 === "string") {
25930
- this[BUFFER$1][0] = c$1.slice(n$1);
25931
- chunk = c$1.slice(0, n$1);
25932
- this[BUFFERLENGTH] -= n$1;
25933
- } else {
25934
- this[BUFFER$1][0] = c$1.subarray(n$1);
25935
- chunk = c$1.subarray(0, n$1);
25936
- this[BUFFERLENGTH] -= n$1;
26290
+ process.stdout.write(moveUp);
26291
+ for (const line of lines) console.log(theme.colors.base44Orange(line));
26292
+ }
26293
+ /**
26294
+ * Animate the output with a smooth line-by-line reveal.
26295
+ * Each line fades in with a gradient sweep effect.
26296
+ *
26297
+ * Total duration: ~1.5 seconds for a magical but not slow feel.
26298
+ */
26299
+ async function printAnimatedLines(lines) {
26300
+ const lineDelay = 1e3 / lines.length;
26301
+ for (let i$1 = 0; i$1 < lines.length; i$1++) {
26302
+ const line = lines[i$1];
26303
+ await animateLineReveal(line, 100);
26304
+ if (i$1 < lines.length - 1) await sleep(lineDelay - 100);
26305
+ }
26306
+ await shimmerPass(lines, 200);
26307
+ }
26308
+
26309
+ //#endregion
26310
+ //#region src/cli/utils/banner.ts
26311
+ const BANNER_LINES = [
26312
+ "██████╗ █████╗ ███████╗███████╗ ██╗ ██╗██╗ ██╗",
26313
+ "██╔══██╗██╔══██╗██╔════╝██╔════╝ ██║ ██║██║ ██║",
26314
+ "██████╔╝███████║███████╗█████╗ ███████║███████║",
26315
+ "██╔══██╗██╔══██║╚════██║██╔══╝ ╚════██║╚════██║",
26316
+ "██████╔╝██║ ██║███████║███████╗ ██║ ██║",
26317
+ "╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝"
26318
+ ];
26319
+ /**
26320
+ * Print the Base44 banner with smooth animation if supported,
26321
+ * or fall back to static banner.
26322
+ */
26323
+ async function printBanner() {
26324
+ if (process.stdout.isTTY) await printAnimatedLines(BANNER_LINES);
26325
+ else console.log(theme.colors.base44Orange(BANNER_LINES.join("\n")));
26326
+ }
26327
+
26328
+ //#endregion
26329
+ //#region src/cli/utils/runCommand.ts
26330
+ /**
26331
+ * Wraps a command function with the Base44 intro/outro and error handling.
26332
+ * All CLI commands should use this utility to ensure consistent branding.
26333
+ *
26334
+ * **Responsibilities**:
26335
+ * - Displays the intro (simple tag or full ASCII banner)
26336
+ * - Loads `.env.local` from the project root if available
26337
+ * - Checks authentication if `requireAuth` is set
26338
+ * - Runs the command function
26339
+ * - Displays the outro message returned by the command
26340
+ * - Handles errors and exits with code 1 on failure
26341
+ *
26342
+ * **Important**: Commands should NOT call `intro()` or `outro()` directly.
26343
+ * This function handles both. Commands can return an optional `outroMessage`
26344
+ * which will be displayed at the end.
26345
+ *
26346
+ * @param commandFn - The async function to execute. Returns `RunCommandResult` with optional `outroMessage`.
26347
+ * @param options - Optional configuration for the command wrapper
26348
+ *
26349
+ * @example
26350
+ * // Standard command with outro message
26351
+ * async function myAction(): Promise<RunCommandResult> {
26352
+ * // ... do work ...
26353
+ * return { outroMessage: "Done!" };
26354
+ * }
26355
+ *
26356
+ * export const myCommand = new Command("my-command")
26357
+ * .action(async () => {
26358
+ * await runCommand(myAction);
26359
+ * });
26360
+ *
26361
+ * @example
26362
+ * // Command requiring authentication with full banner
26363
+ * export const myCommand = new Command("my-command")
26364
+ * .action(async () => {
26365
+ * await runCommand(myAction, { requireAuth: true, fullBanner: true });
26366
+ * });
26367
+ */
26368
+ async function runCommand(commandFn, options) {
26369
+ console.log();
26370
+ if (options?.fullBanner) {
26371
+ await printBanner();
26372
+ Ie("");
26373
+ } else Ie(theme.colors.base44OrangeBackground(" Base 44 "));
26374
+ await loadProjectEnv();
26375
+ try {
26376
+ if (options?.requireAuth) {
26377
+ if (!await isLoggedIn()) {
26378
+ M.info("You need to login first to continue.");
26379
+ await login();
25937
26380
  }
25938
26381
  }
25939
- this.emit("data", chunk);
25940
- if (!this[BUFFER$1].length && !this[EOF$1]) this.emit("drain");
25941
- return chunk;
26382
+ const { outroMessage } = await commandFn();
26383
+ Se(outroMessage || "");
26384
+ } catch (e$1) {
26385
+ if (e$1 instanceof Error) M.error(e$1.stack ?? e$1.message);
26386
+ else M.error(String(e$1));
26387
+ process.exit(1);
25942
26388
  }
25943
- end(chunk, encoding, cb) {
25944
- if (typeof chunk === "function") {
25945
- cb = chunk;
25946
- chunk = void 0;
25947
- }
25948
- if (typeof encoding === "function") {
25949
- cb = encoding;
25950
- encoding = "utf8";
25951
- }
25952
- if (chunk !== void 0) this.write(chunk, encoding);
25953
- if (cb) this.once("end", cb);
25954
- this[EOF$1] = true;
25955
- this.writable = false;
25956
- if (this[FLOWING] || !this[PAUSED]) this[MAYBE_EMIT_END]();
25957
- return this;
26389
+ }
26390
+
26391
+ //#endregion
26392
+ //#region src/cli/utils/runTask.ts
26393
+ /**
26394
+ * Wraps an async operation with automatic spinner management.
26395
+ * The spinner is automatically started, and stopped on both success and error.
26396
+ *
26397
+ * @param startMessage - Message to show when spinner starts
26398
+ * @param operation - The async operation to execute. Receives an updateMessage function
26399
+ * to update the spinner text during long-running operations.
26400
+ * @param options - Optional configuration for success/error messages
26401
+ * @returns The result of the operation
26402
+ *
26403
+ * @example
26404
+ * // Simple usage
26405
+ * const data = await runTask(
26406
+ * "Fetching data...",
26407
+ * async () => {
26408
+ * const response = await fetch(url);
26409
+ * return response.json();
26410
+ * },
26411
+ * {
26412
+ * successMessage: "Data fetched successfully",
26413
+ * errorMessage: "Failed to fetch data",
26414
+ * }
26415
+ * );
26416
+ *
26417
+ * @example
26418
+ * // With progress updates
26419
+ * const result = await runTask(
26420
+ * "Processing files...",
26421
+ * async (updateMessage) => {
26422
+ * for (const file of files) {
26423
+ * updateMessage(`Processing ${file.name}...`);
26424
+ * await process(file);
26425
+ * }
26426
+ * return files.length;
26427
+ * },
26428
+ * { successMessage: "All files processed" }
26429
+ * );
26430
+ */
26431
+ async function runTask(startMessage, operation, options) {
26432
+ const s = Y();
26433
+ s.start(startMessage);
26434
+ const updateMessage = (message) => s.message(message);
26435
+ try {
26436
+ const result = await operation(updateMessage);
26437
+ s.stop(options?.successMessage || startMessage);
26438
+ return result;
26439
+ } catch (error) {
26440
+ s.stop(options?.errorMessage || "Failed");
26441
+ throw error;
25958
26442
  }
25959
- [RESUME]() {
25960
- if (this[DESTROYED]) return;
25961
- if (!this[DATALISTENERS] && !this[PIPES].length) this[DISCARDED] = true;
25962
- this[PAUSED] = false;
25963
- this[FLOWING] = true;
25964
- this.emit("resume");
25965
- if (this[BUFFER$1].length) this[FLUSH]();
25966
- else if (this[EOF$1]) this[MAYBE_EMIT_END]();
25967
- else this.emit("drain");
26443
+ }
26444
+
26445
+ //#endregion
26446
+ //#region src/cli/utils/prompts.ts
26447
+ /**
26448
+ * Standard onCancel handler for prompt groups.
26449
+ * Exits the process gracefully when the user cancels.
26450
+ */
26451
+ const onPromptCancel = () => {
26452
+ xe("Operation cancelled.");
26453
+ process.exit(0);
26454
+ };
26455
+
26456
+ //#endregion
26457
+ //#region src/cli/commands/auth/login.ts
26458
+ async function generateAndDisplayDeviceCode() {
26459
+ const deviceCodeResponse = await runTask("Generating device code...", async () => {
26460
+ return await generateDeviceCode();
26461
+ }, {
26462
+ successMessage: "Device code generated",
26463
+ errorMessage: "Failed to generate device code"
26464
+ });
26465
+ M.info(`Verification code: ${theme.styles.bold(deviceCodeResponse.userCode)}\nPlease confirm this code at: ${deviceCodeResponse.verificationUri}`);
26466
+ return deviceCodeResponse;
26467
+ }
26468
+ async function waitForAuthentication(deviceCode, expiresIn, interval) {
26469
+ let tokenResponse;
26470
+ try {
26471
+ await runTask("Waiting for authentication...", async () => {
26472
+ await pWaitFor(async () => {
26473
+ const result = await getTokenFromDeviceCode(deviceCode);
26474
+ if (result !== null) {
26475
+ tokenResponse = result;
26476
+ return true;
26477
+ }
26478
+ return false;
26479
+ }, {
26480
+ interval: interval * 1e3,
26481
+ timeout: expiresIn * 1e3
26482
+ });
26483
+ }, {
26484
+ successMessage: "Authentication completed!",
26485
+ errorMessage: "Authentication failed"
26486
+ });
26487
+ } catch (error) {
26488
+ if (error instanceof Error && error.message.includes("timed out")) throw new Error("Authentication timed out. Please try again.");
26489
+ throw error;
26490
+ }
26491
+ if (tokenResponse === void 0) throw new Error("Failed to retrieve authentication token.");
26492
+ return tokenResponse;
26493
+ }
26494
+ async function saveAuthData(response, userInfo) {
26495
+ const expiresAt = Date.now() + response.expiresIn * 1e3;
26496
+ await writeAuth({
26497
+ accessToken: response.accessToken,
26498
+ refreshToken: response.refreshToken,
26499
+ expiresAt,
26500
+ email: userInfo.email,
26501
+ name: userInfo.name
26502
+ });
26503
+ }
26504
+ async function login() {
26505
+ const deviceCodeResponse = await generateAndDisplayDeviceCode();
26506
+ const token = await waitForAuthentication(deviceCodeResponse.deviceCode, deviceCodeResponse.expiresIn, deviceCodeResponse.interval);
26507
+ const userInfo = await getUserInfo(token.accessToken);
26508
+ await saveAuthData(token, userInfo);
26509
+ return { outroMessage: `Successfully logged in as ${theme.styles.bold(userInfo.email)}` };
26510
+ }
26511
+ const loginCommand = new Command("login").description("Authenticate with Base44").action(async () => {
26512
+ await runCommand(login);
26513
+ });
26514
+
26515
+ //#endregion
26516
+ //#region src/cli/commands/auth/whoami.ts
26517
+ async function whoami() {
26518
+ const auth = await readAuth();
26519
+ return { outroMessage: `Logged in as: ${theme.styles.bold(auth.email)}` };
26520
+ }
26521
+ const whoamiCommand = new Command("whoami").description("Display current authenticated user").action(async () => {
26522
+ await runCommand(whoami, { requireAuth: true });
26523
+ });
26524
+
26525
+ //#endregion
26526
+ //#region src/cli/commands/auth/logout.ts
26527
+ async function logout() {
26528
+ await deleteAuth();
26529
+ return { outroMessage: "Logged out successfully" };
26530
+ }
26531
+ const logoutCommand = new Command("logout").description("Logout from current device").action(async () => {
26532
+ await runCommand(logout);
26533
+ });
26534
+
26535
+ //#endregion
26536
+ //#region src/core/site/schema.ts
26537
+ /**
26538
+ * Response from the deploy API endpoint.
26539
+ */
26540
+ const DeployResponseSchema = object({ app_url: url() }).transform((data) => ({ appUrl: data.app_url }));
26541
+
26542
+ //#endregion
26543
+ //#region src/core/site/config.ts
26544
+ /**
26545
+ * Gets all file paths in the output directory.
26546
+ * Used to check if the directory contains any files before deployment.
26547
+ *
26548
+ * @param outputDir - The directory containing built site files
26549
+ * @returns Array of relative file paths
26550
+ */
26551
+ async function getSiteFilePaths(outputDir) {
26552
+ return await globby("**/*", {
26553
+ cwd: outputDir,
26554
+ onlyFiles: true,
26555
+ absolute: false
26556
+ });
26557
+ }
26558
+
26559
+ //#endregion
26560
+ //#region src/core/site/api.ts
26561
+ /**
26562
+ * Uploads a tar.gz archive file to the Base44 hosting API.
26563
+ *
26564
+ * @param archivePath - Path to the tar.gz archive file
26565
+ * @returns Deploy response with the site URL and deployment details
26566
+ * @throws Error if file read or upload fails
26567
+ */
26568
+ async function uploadSite(archivePath) {
26569
+ const archiveBuffer = await readFile$1(archivePath);
26570
+ const blob = new Blob([archiveBuffer], { type: "application/gzip" });
26571
+ const formData = new FormData();
26572
+ formData.append("file", blob, "dist.tar.gz");
26573
+ const response = await getAppClient().post("deploy-dist", { body: formData });
26574
+ return DeployResponseSchema.parse(await response.json());
26575
+ }
26576
+
26577
+ //#endregion
26578
+ //#region node_modules/minipass/dist/esm/index.js
26579
+ const proc = typeof process === "object" && process ? process : {
26580
+ stdout: null,
26581
+ stderr: null
26582
+ };
26583
+ /**
26584
+ * Return true if the argument is a Minipass stream, Node stream, or something
26585
+ * else that Minipass can interact with.
26586
+ */
26587
+ const isStream$1 = (s) => !!s && typeof s === "object" && (s instanceof Minipass || s instanceof Stream || isReadable(s) || isWritable(s));
26588
+ /**
26589
+ * Return true if the argument is a valid {@link Minipass.Readable}
26590
+ */
26591
+ const isReadable = (s) => !!s && typeof s === "object" && s instanceof EventEmitter && typeof s.pipe === "function" && s.pipe !== Stream.Writable.prototype.pipe;
26592
+ /**
26593
+ * Return true if the argument is a valid {@link Minipass.Writable}
26594
+ */
26595
+ const isWritable = (s) => !!s && typeof s === "object" && s instanceof EventEmitter && typeof s.write === "function" && typeof s.end === "function";
26596
+ const EOF$1 = Symbol("EOF");
26597
+ const MAYBE_EMIT_END = Symbol("maybeEmitEnd");
26598
+ const EMITTED_END = Symbol("emittedEnd");
26599
+ const EMITTING_END = Symbol("emittingEnd");
26600
+ const EMITTED_ERROR = Symbol("emittedError");
26601
+ const CLOSED = Symbol("closed");
26602
+ const READ$1 = Symbol("read");
26603
+ const FLUSH = Symbol("flush");
26604
+ const FLUSHCHUNK = Symbol("flushChunk");
26605
+ const ENCODING = Symbol("encoding");
26606
+ const DECODER = Symbol("decoder");
26607
+ const FLOWING = Symbol("flowing");
26608
+ const PAUSED = Symbol("paused");
26609
+ const RESUME = Symbol("resume");
26610
+ const BUFFER$1 = Symbol("buffer");
26611
+ const PIPES = Symbol("pipes");
26612
+ const BUFFERLENGTH = Symbol("bufferLength");
26613
+ const BUFFERPUSH = Symbol("bufferPush");
26614
+ const BUFFERSHIFT = Symbol("bufferShift");
26615
+ const OBJECTMODE = Symbol("objectMode");
26616
+ const DESTROYED = Symbol("destroyed");
26617
+ const ERROR = Symbol("error");
26618
+ const EMITDATA = Symbol("emitData");
26619
+ const EMITEND = Symbol("emitEnd");
26620
+ const EMITEND2 = Symbol("emitEnd2");
26621
+ const ASYNC = Symbol("async");
26622
+ const ABORT = Symbol("abort");
26623
+ const ABORTED$1 = Symbol("aborted");
26624
+ const SIGNAL = Symbol("signal");
26625
+ const DATALISTENERS = Symbol("dataListeners");
26626
+ const DISCARDED = Symbol("discarded");
26627
+ const defer = (fn) => Promise.resolve().then(fn);
26628
+ const nodefer = (fn) => fn();
26629
+ const isEndish = (ev) => ev === "end" || ev === "finish" || ev === "prefinish";
26630
+ const isArrayBufferLike = (b$2) => b$2 instanceof ArrayBuffer || !!b$2 && typeof b$2 === "object" && b$2.constructor && b$2.constructor.name === "ArrayBuffer" && b$2.byteLength >= 0;
26631
+ const isArrayBufferView = (b$2) => !Buffer.isBuffer(b$2) && ArrayBuffer.isView(b$2);
26632
+ /**
26633
+ * Internal class representing a pipe to a destination stream.
26634
+ *
26635
+ * @internal
26636
+ */
26637
+ var Pipe = class {
26638
+ src;
26639
+ dest;
26640
+ opts;
26641
+ ondrain;
26642
+ constructor(src, dest, opts) {
26643
+ this.src = src;
26644
+ this.dest = dest;
26645
+ this.opts = opts;
26646
+ this.ondrain = () => src[RESUME]();
26647
+ this.dest.on("drain", this.ondrain);
26648
+ }
26649
+ unpipe() {
26650
+ this.dest.removeListener("drain", this.ondrain);
26651
+ }
26652
+ /* c8 ignore start */
26653
+ proxyErrors(_er) {}
26654
+ /* c8 ignore stop */
26655
+ end() {
26656
+ this.unpipe();
26657
+ if (this.opts.end) this.dest.end();
26658
+ }
26659
+ };
26660
+ /**
26661
+ * Internal class representing a pipe to a destination stream where
26662
+ * errors are proxied.
26663
+ *
26664
+ * @internal
26665
+ */
26666
+ var PipeProxyErrors = class extends Pipe {
26667
+ unpipe() {
26668
+ this.src.removeListener("error", this.proxyErrors);
26669
+ super.unpipe();
26670
+ }
26671
+ constructor(src, dest, opts) {
26672
+ super(src, dest, opts);
26673
+ this.proxyErrors = (er) => dest.emit("error", er);
26674
+ src.on("error", this.proxyErrors);
25968
26675
  }
26676
+ };
26677
+ const isObjectModeOptions = (o$2) => !!o$2.objectMode;
26678
+ const isEncodingOptions = (o$2) => !o$2.objectMode && !!o$2.encoding && o$2.encoding !== "buffer";
26679
+ /**
26680
+ * Main export, the Minipass class
26681
+ *
26682
+ * `RType` is the type of data emitted, defaults to Buffer
26683
+ *
26684
+ * `WType` is the type of data to be written, if RType is buffer or string,
26685
+ * then any {@link Minipass.ContiguousData} is allowed.
26686
+ *
26687
+ * `Events` is the set of event handler signatures that this object
26688
+ * will emit, see {@link Minipass.Events}
26689
+ */
26690
+ var Minipass = class extends EventEmitter {
26691
+ [FLOWING] = false;
26692
+ [PAUSED] = false;
26693
+ [PIPES] = [];
26694
+ [BUFFER$1] = [];
26695
+ [OBJECTMODE];
26696
+ [ENCODING];
26697
+ [ASYNC];
26698
+ [DECODER];
26699
+ [EOF$1] = false;
26700
+ [EMITTED_END] = false;
26701
+ [EMITTING_END] = false;
26702
+ [CLOSED] = false;
26703
+ [EMITTED_ERROR] = null;
26704
+ [BUFFERLENGTH] = 0;
26705
+ [DESTROYED] = false;
26706
+ [SIGNAL];
26707
+ [ABORTED$1] = false;
26708
+ [DATALISTENERS] = 0;
26709
+ [DISCARDED] = false;
25969
26710
  /**
25970
- * Resume the stream if it is currently in a paused state
25971
- *
25972
- * If called when there are no pipe destinations or `data` event listeners,
25973
- * this will place the stream in a "discarded" state, where all data will
25974
- * be thrown away. The discarded state is removed if a pipe destination or
25975
- * data handler is added, if pause() is called, or if any synchronous or
25976
- * asynchronous iteration is started.
26711
+ * true if the stream can be written
25977
26712
  */
25978
- resume() {
25979
- return this[RESUME]();
25980
- }
26713
+ writable = true;
25981
26714
  /**
25982
- * Pause the stream
26715
+ * true if the stream can be read
25983
26716
  */
25984
- pause() {
25985
- this[FLOWING] = false;
25986
- this[PAUSED] = true;
25987
- this[DISCARDED] = false;
25988
- }
26717
+ readable = true;
25989
26718
  /**
25990
- * true if the stream has been forcibly destroyed
26719
+ * If `RType` is Buffer, then options do not need to be provided.
26720
+ * Otherwise, an options object must be provided to specify either
26721
+ * {@link Minipass.SharedOptions.objectMode} or
26722
+ * {@link Minipass.SharedOptions.encoding}, as appropriate.
25991
26723
  */
25992
- get destroyed() {
25993
- return this[DESTROYED];
26724
+ constructor(...args) {
26725
+ const options = args[0] || {};
26726
+ super();
26727
+ if (options.objectMode && typeof options.encoding === "string") throw new TypeError("Encoding and objectMode may not be used together");
26728
+ if (isObjectModeOptions(options)) {
26729
+ this[OBJECTMODE] = true;
26730
+ this[ENCODING] = null;
26731
+ } else if (isEncodingOptions(options)) {
26732
+ this[ENCODING] = options.encoding;
26733
+ this[OBJECTMODE] = false;
26734
+ } else {
26735
+ this[OBJECTMODE] = false;
26736
+ this[ENCODING] = null;
26737
+ }
26738
+ this[ASYNC] = !!options.async;
26739
+ this[DECODER] = this[ENCODING] ? new StringDecoder(this[ENCODING]) : null;
26740
+ if (options && options.debugExposeBuffer === true) Object.defineProperty(this, "buffer", { get: () => this[BUFFER$1] });
26741
+ if (options && options.debugExposePipes === true) Object.defineProperty(this, "pipes", { get: () => this[PIPES] });
26742
+ const { signal } = options;
26743
+ if (signal) {
26744
+ this[SIGNAL] = signal;
26745
+ if (signal.aborted) this[ABORT]();
26746
+ else signal.addEventListener("abort", () => this[ABORT]());
26747
+ }
25994
26748
  }
25995
26749
  /**
25996
- * true if the stream is currently in a flowing state, meaning that
25997
- * any writes will be immediately emitted.
26750
+ * The amount of data stored in the buffer waiting to be read.
26751
+ *
26752
+ * For Buffer strings, this will be the total byte length.
26753
+ * For string encoding streams, this will be the string character length,
26754
+ * according to JavaScript's `string.length` logic.
26755
+ * For objectMode streams, this is a count of the items waiting to be
26756
+ * emitted.
25998
26757
  */
25999
- get flowing() {
26000
- return this[FLOWING];
26758
+ get bufferLength() {
26759
+ return this[BUFFERLENGTH];
26760
+ }
26761
+ /**
26762
+ * The `BufferEncoding` currently in use, or `null`
26763
+ */
26764
+ get encoding() {
26765
+ return this[ENCODING];
26766
+ }
26767
+ /**
26768
+ * @deprecated - This is a read only property
26769
+ */
26770
+ set encoding(_enc) {
26771
+ throw new Error("Encoding must be set at instantiation time");
26772
+ }
26773
+ /**
26774
+ * @deprecated - Encoding may only be set at instantiation time
26775
+ */
26776
+ setEncoding(_enc) {
26777
+ throw new Error("Encoding must be set at instantiation time");
26778
+ }
26779
+ /**
26780
+ * True if this is an objectMode stream
26781
+ */
26782
+ get objectMode() {
26783
+ return this[OBJECTMODE];
26784
+ }
26785
+ /**
26786
+ * @deprecated - This is a read-only property
26787
+ */
26788
+ set objectMode(_om) {
26789
+ throw new Error("objectMode must be set at instantiation time");
26790
+ }
26791
+ /**
26792
+ * true if this is an async stream
26793
+ */
26794
+ get ["async"]() {
26795
+ return this[ASYNC];
26796
+ }
26797
+ /**
26798
+ * Set to true to make this stream async.
26799
+ *
26800
+ * Once set, it cannot be unset, as this would potentially cause incorrect
26801
+ * behavior. Ie, a sync stream can be made async, but an async stream
26802
+ * cannot be safely made sync.
26803
+ */
26804
+ set ["async"](a$1) {
26805
+ this[ASYNC] = this[ASYNC] || !!a$1;
26806
+ }
26807
+ [ABORT]() {
26808
+ this[ABORTED$1] = true;
26809
+ this.emit("abort", this[SIGNAL]?.reason);
26810
+ this.destroy(this[SIGNAL]?.reason);
26811
+ }
26812
+ /**
26813
+ * True if the stream has been aborted.
26814
+ */
26815
+ get aborted() {
26816
+ return this[ABORTED$1];
26817
+ }
26818
+ /**
26819
+ * No-op setter. Stream aborted status is set via the AbortSignal provided
26820
+ * in the constructor options.
26821
+ */
26822
+ set aborted(_$2) {}
26823
+ write(chunk, encoding, cb) {
26824
+ if (this[ABORTED$1]) return false;
26825
+ if (this[EOF$1]) throw new Error("write after end");
26826
+ if (this[DESTROYED]) {
26827
+ this.emit("error", Object.assign(/* @__PURE__ */ new Error("Cannot call write after a stream was destroyed"), { code: "ERR_STREAM_DESTROYED" }));
26828
+ return true;
26829
+ }
26830
+ if (typeof encoding === "function") {
26831
+ cb = encoding;
26832
+ encoding = "utf8";
26833
+ }
26834
+ if (!encoding) encoding = "utf8";
26835
+ const fn = this[ASYNC] ? defer : nodefer;
26836
+ if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
26837
+ if (isArrayBufferView(chunk)) chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
26838
+ else if (isArrayBufferLike(chunk)) chunk = Buffer.from(chunk);
26839
+ else if (typeof chunk !== "string") throw new Error("Non-contiguous data written to non-objectMode stream");
26840
+ }
26841
+ if (this[OBJECTMODE]) {
26842
+ /* c8 ignore start */
26843
+ if (this[FLOWING] && this[BUFFERLENGTH] !== 0) this[FLUSH](true);
26844
+ /* c8 ignore stop */
26845
+ if (this[FLOWING]) this.emit("data", chunk);
26846
+ else this[BUFFERPUSH](chunk);
26847
+ if (this[BUFFERLENGTH] !== 0) this.emit("readable");
26848
+ if (cb) fn(cb);
26849
+ return this[FLOWING];
26850
+ }
26851
+ if (!chunk.length) {
26852
+ if (this[BUFFERLENGTH] !== 0) this.emit("readable");
26853
+ if (cb) fn(cb);
26854
+ return this[FLOWING];
26855
+ }
26856
+ if (typeof chunk === "string" && !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) chunk = Buffer.from(chunk, encoding);
26857
+ if (Buffer.isBuffer(chunk) && this[ENCODING]) chunk = this[DECODER].write(chunk);
26858
+ if (this[FLOWING] && this[BUFFERLENGTH] !== 0) this[FLUSH](true);
26859
+ if (this[FLOWING]) this.emit("data", chunk);
26860
+ else this[BUFFERPUSH](chunk);
26861
+ if (this[BUFFERLENGTH] !== 0) this.emit("readable");
26862
+ if (cb) fn(cb);
26863
+ return this[FLOWING];
26864
+ }
26865
+ /**
26866
+ * Low-level explicit read method.
26867
+ *
26868
+ * In objectMode, the argument is ignored, and one item is returned if
26869
+ * available.
26870
+ *
26871
+ * `n` is the number of bytes (or in the case of encoding streams,
26872
+ * characters) to consume. If `n` is not provided, then the entire buffer
26873
+ * is returned, or `null` is returned if no data is available.
26874
+ *
26875
+ * If `n` is greater that the amount of data in the internal buffer,
26876
+ * then `null` is returned.
26877
+ */
26878
+ read(n$1) {
26879
+ if (this[DESTROYED]) return null;
26880
+ this[DISCARDED] = false;
26881
+ if (this[BUFFERLENGTH] === 0 || n$1 === 0 || n$1 && n$1 > this[BUFFERLENGTH]) {
26882
+ this[MAYBE_EMIT_END]();
26883
+ return null;
26884
+ }
26885
+ if (this[OBJECTMODE]) n$1 = null;
26886
+ if (this[BUFFER$1].length > 1 && !this[OBJECTMODE]) this[BUFFER$1] = [this[ENCODING] ? this[BUFFER$1].join("") : Buffer.concat(this[BUFFER$1], this[BUFFERLENGTH])];
26887
+ const ret = this[READ$1](n$1 || null, this[BUFFER$1][0]);
26888
+ this[MAYBE_EMIT_END]();
26889
+ return ret;
26890
+ }
26891
+ [READ$1](n$1, chunk) {
26892
+ if (this[OBJECTMODE]) this[BUFFERSHIFT]();
26893
+ else {
26894
+ const c$1 = chunk;
26895
+ if (n$1 === c$1.length || n$1 === null) this[BUFFERSHIFT]();
26896
+ else if (typeof c$1 === "string") {
26897
+ this[BUFFER$1][0] = c$1.slice(n$1);
26898
+ chunk = c$1.slice(0, n$1);
26899
+ this[BUFFERLENGTH] -= n$1;
26900
+ } else {
26901
+ this[BUFFER$1][0] = c$1.subarray(n$1);
26902
+ chunk = c$1.subarray(0, n$1);
26903
+ this[BUFFERLENGTH] -= n$1;
26904
+ }
26905
+ }
26906
+ this.emit("data", chunk);
26907
+ if (!this[BUFFER$1].length && !this[EOF$1]) this.emit("drain");
26908
+ return chunk;
26909
+ }
26910
+ end(chunk, encoding, cb) {
26911
+ if (typeof chunk === "function") {
26912
+ cb = chunk;
26913
+ chunk = void 0;
26914
+ }
26915
+ if (typeof encoding === "function") {
26916
+ cb = encoding;
26917
+ encoding = "utf8";
26918
+ }
26919
+ if (chunk !== void 0) this.write(chunk, encoding);
26920
+ if (cb) this.once("end", cb);
26921
+ this[EOF$1] = true;
26922
+ this.writable = false;
26923
+ if (this[FLOWING] || !this[PAUSED]) this[MAYBE_EMIT_END]();
26924
+ return this;
26925
+ }
26926
+ [RESUME]() {
26927
+ if (this[DESTROYED]) return;
26928
+ if (!this[DATALISTENERS] && !this[PIPES].length) this[DISCARDED] = true;
26929
+ this[PAUSED] = false;
26930
+ this[FLOWING] = true;
26931
+ this.emit("resume");
26932
+ if (this[BUFFER$1].length) this[FLUSH]();
26933
+ else if (this[EOF$1]) this[MAYBE_EMIT_END]();
26934
+ else this.emit("drain");
26935
+ }
26936
+ /**
26937
+ * Resume the stream if it is currently in a paused state
26938
+ *
26939
+ * If called when there are no pipe destinations or `data` event listeners,
26940
+ * this will place the stream in a "discarded" state, where all data will
26941
+ * be thrown away. The discarded state is removed if a pipe destination or
26942
+ * data handler is added, if pause() is called, or if any synchronous or
26943
+ * asynchronous iteration is started.
26944
+ */
26945
+ resume() {
26946
+ return this[RESUME]();
26947
+ }
26948
+ /**
26949
+ * Pause the stream
26950
+ */
26951
+ pause() {
26952
+ this[FLOWING] = false;
26953
+ this[PAUSED] = true;
26954
+ this[DISCARDED] = false;
26955
+ }
26956
+ /**
26957
+ * true if the stream has been forcibly destroyed
26958
+ */
26959
+ get destroyed() {
26960
+ return this[DESTROYED];
26961
+ }
26962
+ /**
26963
+ * true if the stream is currently in a flowing state, meaning that
26964
+ * any writes will be immediately emitted.
26965
+ */
26966
+ get flowing() {
26967
+ return this[FLOWING];
26001
26968
  }
26002
26969
  /**
26003
26970
  * true if the stream is currently in a paused state
@@ -30021,1562 +30988,532 @@ var Unpack = class extends Parser {
30021
30988
  };
30022
30989
  stream.on("finish", () => {
30023
30990
  const abs = String(entry.absolute);
30024
- const fd = stream.fd;
30025
- if (typeof fd === "number" && entry.mtime && !this.noMtime) {
30026
- actions++;
30027
- const atime = entry.atime || /* @__PURE__ */ new Date();
30028
- const mtime = entry.mtime;
30029
- fs.futimes(fd, atime, mtime, (er) => er ? fs.utimes(abs, atime, mtime, (er2) => done(er2 && er)) : done());
30030
- }
30031
- if (typeof fd === "number" && this[DOCHOWN](entry)) {
30032
- actions++;
30033
- const uid = this[UID](entry);
30034
- const gid = this[GID](entry);
30035
- if (typeof uid === "number" && typeof gid === "number") fs.fchown(fd, uid, gid, (er) => er ? fs.chown(abs, uid, gid, (er2) => done(er2 && er)) : done());
30036
- }
30037
- done();
30038
- });
30039
- const tx = this.transform ? this.transform(entry) || entry : entry;
30040
- if (tx !== entry) {
30041
- tx.on("error", (er) => {
30042
- this[ONERROR](er, entry);
30043
- fullyDone();
30044
- });
30045
- entry.pipe(tx);
30046
- }
30047
- tx.pipe(stream);
30048
- }
30049
- [DIRECTORY](entry, fullyDone) {
30050
- const mode = typeof entry.mode === "number" ? entry.mode & 4095 : this.dmode;
30051
- this[MKDIR](String(entry.absolute), mode, (er) => {
30052
- if (er) {
30053
- this[ONERROR](er, entry);
30054
- fullyDone();
30055
- return;
30056
- }
30057
- let actions = 1;
30058
- const done = () => {
30059
- if (--actions === 0) {
30060
- fullyDone();
30061
- this[UNPEND]();
30062
- entry.resume();
30063
- }
30064
- };
30065
- if (entry.mtime && !this.noMtime) {
30066
- actions++;
30067
- fs.utimes(String(entry.absolute), entry.atime || /* @__PURE__ */ new Date(), entry.mtime, done);
30068
- }
30069
- if (this[DOCHOWN](entry)) {
30070
- actions++;
30071
- fs.chown(String(entry.absolute), Number(this[UID](entry)), Number(this[GID](entry)), done);
30072
- }
30073
- done();
30074
- });
30075
- }
30076
- [UNSUPPORTED](entry) {
30077
- entry.unsupported = true;
30078
- this.warn("TAR_ENTRY_UNSUPPORTED", `unsupported entry type: ${entry.type}`, { entry });
30079
- entry.resume();
30080
- }
30081
- [SYMLINK](entry, done) {
30082
- this[LINK](entry, String(entry.linkpath), "symlink", done);
30083
- }
30084
- [HARDLINK](entry, done) {
30085
- const linkpath = normalizeWindowsPath(path.resolve(this.cwd, String(entry.linkpath)));
30086
- this[LINK](entry, linkpath, "link", done);
30087
- }
30088
- [PEND]() {
30089
- this[PENDING]++;
30090
- }
30091
- [UNPEND]() {
30092
- this[PENDING]--;
30093
- this[MAYBECLOSE]();
30094
- }
30095
- [SKIP](entry) {
30096
- this[UNPEND]();
30097
- entry.resume();
30098
- }
30099
- [ISREUSABLE](entry, st) {
30100
- return entry.type === "File" && !this.unlink && st.isFile() && st.nlink <= 1 && !isWindows;
30101
- }
30102
- [CHECKFS](entry) {
30103
- this[PEND]();
30104
- const paths = [entry.path];
30105
- if (entry.linkpath) paths.push(entry.linkpath);
30106
- this.reservations.reserve(paths, (done) => this[CHECKFS2](entry, done));
30107
- }
30108
- [CHECKFS2](entry, fullyDone) {
30109
- const done = (er) => {
30110
- fullyDone(er);
30111
- };
30112
- const checkCwd$1 = () => {
30113
- this[MKDIR](this.cwd, this.dmode, (er) => {
30114
- if (er) {
30115
- this[ONERROR](er, entry);
30116
- done();
30117
- return;
30118
- }
30119
- this[CHECKED_CWD] = true;
30120
- start();
30121
- });
30122
- };
30123
- const start = () => {
30124
- if (entry.absolute !== this.cwd) {
30125
- const parent = normalizeWindowsPath(path.dirname(String(entry.absolute)));
30126
- if (parent !== this.cwd) return this[MKDIR](parent, this.dmode, (er) => {
30127
- if (er) {
30128
- this[ONERROR](er, entry);
30129
- done();
30130
- return;
30131
- }
30132
- afterMakeParent();
30133
- });
30134
- }
30135
- afterMakeParent();
30136
- };
30137
- const afterMakeParent = () => {
30138
- fs.lstat(String(entry.absolute), (lstatEr, st) => {
30139
- if (st && (this.keep || this.newer && st.mtime > (entry.mtime ?? st.mtime))) {
30140
- this[SKIP](entry);
30141
- done();
30142
- return;
30143
- }
30144
- if (lstatEr || this[ISREUSABLE](entry, st)) return this[MAKEFS](null, entry, done);
30145
- if (st.isDirectory()) {
30146
- if (entry.type === "Directory") {
30147
- const needChmod = this.chmod && entry.mode && (st.mode & 4095) !== entry.mode;
30148
- const afterChmod = (er) => this[MAKEFS](er ?? null, entry, done);
30149
- if (!needChmod) return afterChmod();
30150
- return fs.chmod(String(entry.absolute), Number(entry.mode), afterChmod);
30151
- }
30152
- if (entry.absolute !== this.cwd) return fs.rmdir(String(entry.absolute), (er) => this[MAKEFS](er ?? null, entry, done));
30153
- }
30154
- if (entry.absolute === this.cwd) return this[MAKEFS](null, entry, done);
30155
- unlinkFile(String(entry.absolute), (er) => this[MAKEFS](er ?? null, entry, done));
30156
- });
30157
- };
30158
- if (this[CHECKED_CWD]) start();
30159
- else checkCwd$1();
30160
- }
30161
- [MAKEFS](er, entry, done) {
30162
- if (er) {
30163
- this[ONERROR](er, entry);
30164
- done();
30165
- return;
30166
- }
30167
- switch (entry.type) {
30168
- case "File":
30169
- case "OldFile":
30170
- case "ContiguousFile": return this[FILE](entry, done);
30171
- case "Link": return this[HARDLINK](entry, done);
30172
- case "SymbolicLink": return this[SYMLINK](entry, done);
30173
- case "Directory":
30174
- case "GNUDumpDir": return this[DIRECTORY](entry, done);
30175
- }
30176
- }
30177
- [LINK](entry, linkpath, link$1, done) {
30178
- fs[link$1](linkpath, String(entry.absolute), (er) => {
30179
- if (er) this[ONERROR](er, entry);
30180
- else {
30181
- this[UNPEND]();
30182
- entry.resume();
30183
- }
30184
- done();
30185
- });
30186
- }
30187
- };
30188
- const callSync = (fn) => {
30189
- try {
30190
- return [null, fn()];
30191
- } catch (er) {
30192
- return [er, null];
30193
- }
30194
- };
30195
- var UnpackSync = class extends Unpack {
30196
- sync = true;
30197
- [MAKEFS](er, entry) {
30198
- return super[MAKEFS](er, entry, () => {});
30199
- }
30200
- [CHECKFS](entry) {
30201
- if (!this[CHECKED_CWD]) {
30202
- const er$1 = this[MKDIR](this.cwd, this.dmode);
30203
- if (er$1) return this[ONERROR](er$1, entry);
30204
- this[CHECKED_CWD] = true;
30205
- }
30206
- if (entry.absolute !== this.cwd) {
30207
- const parent = normalizeWindowsPath(path.dirname(String(entry.absolute)));
30208
- if (parent !== this.cwd) {
30209
- const mkParent = this[MKDIR](parent, this.dmode);
30210
- if (mkParent) return this[ONERROR](mkParent, entry);
30211
- }
30212
- }
30213
- const [lstatEr, st] = callSync(() => fs.lstatSync(String(entry.absolute)));
30214
- if (st && (this.keep || this.newer && st.mtime > (entry.mtime ?? st.mtime))) return this[SKIP](entry);
30215
- if (lstatEr || this[ISREUSABLE](entry, st)) return this[MAKEFS](null, entry);
30216
- if (st.isDirectory()) {
30217
- if (entry.type === "Directory") {
30218
- const [er$2] = this.chmod && entry.mode && (st.mode & 4095) !== entry.mode ? callSync(() => {
30219
- fs.chmodSync(String(entry.absolute), Number(entry.mode));
30220
- }) : [];
30221
- return this[MAKEFS](er$2, entry);
30222
- }
30223
- const [er$1] = callSync(() => fs.rmdirSync(String(entry.absolute)));
30224
- this[MAKEFS](er$1, entry);
30225
- }
30226
- const [er] = entry.absolute === this.cwd ? [] : callSync(() => unlinkFileSync(String(entry.absolute)));
30227
- this[MAKEFS](er, entry);
30228
- }
30229
- [FILE](entry, done) {
30230
- const mode = typeof entry.mode === "number" ? entry.mode & 4095 : this.fmode;
30231
- const oner = (er) => {
30232
- let closeError;
30233
- try {
30234
- fs.closeSync(fd);
30235
- } catch (e$1) {
30236
- closeError = e$1;
30237
- }
30238
- if (er || closeError) this[ONERROR](er || closeError, entry);
30239
- done();
30240
- };
30241
- let fd;
30242
- try {
30243
- fd = fs.openSync(String(entry.absolute), getWriteFlag(entry.size), mode);
30244
- } catch (er) {
30245
- return oner(er);
30246
- }
30247
- /* c8 ignore stop */
30248
- const tx = this.transform ? this.transform(entry) || entry : entry;
30249
- if (tx !== entry) {
30250
- tx.on("error", (er) => this[ONERROR](er, entry));
30251
- entry.pipe(tx);
30252
- }
30253
- tx.on("data", (chunk) => {
30254
- try {
30255
- fs.writeSync(fd, chunk, 0, chunk.length);
30256
- } catch (er) {
30257
- oner(er);
30258
- }
30259
- });
30260
- tx.on("end", () => {
30261
- let er = null;
30262
- if (entry.mtime && !this.noMtime) {
30263
- const atime = entry.atime || /* @__PURE__ */ new Date();
30264
- const mtime = entry.mtime;
30265
- try {
30266
- fs.futimesSync(fd, atime, mtime);
30267
- } catch (futimeser) {
30268
- try {
30269
- fs.utimesSync(String(entry.absolute), atime, mtime);
30270
- } catch (utimeser) {
30271
- er = futimeser;
30272
- }
30273
- }
30274
- }
30275
- if (this[DOCHOWN](entry)) {
30276
- const uid = this[UID](entry);
30277
- const gid = this[GID](entry);
30278
- try {
30279
- fs.fchownSync(fd, Number(uid), Number(gid));
30280
- } catch (fchowner) {
30281
- try {
30282
- fs.chownSync(String(entry.absolute), Number(uid), Number(gid));
30283
- } catch (chowner) {
30284
- er = er || fchowner;
30285
- }
30286
- }
30287
- }
30288
- oner(er);
30289
- });
30290
- }
30291
- [DIRECTORY](entry, done) {
30292
- const mode = typeof entry.mode === "number" ? entry.mode & 4095 : this.dmode;
30293
- const er = this[MKDIR](String(entry.absolute), mode);
30294
- if (er) {
30295
- this[ONERROR](er, entry);
30296
- done();
30297
- return;
30298
- }
30299
- if (entry.mtime && !this.noMtime) try {
30300
- fs.utimesSync(String(entry.absolute), entry.atime || /* @__PURE__ */ new Date(), entry.mtime);
30301
- } catch (er$1) {}
30302
- if (this[DOCHOWN](entry)) try {
30303
- fs.chownSync(String(entry.absolute), Number(this[UID](entry)), Number(this[GID](entry)));
30304
- } catch (er$1) {}
30305
- done();
30306
- entry.resume();
30307
- }
30308
- [MKDIR](dir, mode) {
30309
- try {
30310
- return mkdirSync(normalizeWindowsPath(dir), {
30311
- uid: this.uid,
30312
- gid: this.gid,
30313
- processUid: this.processUid,
30314
- processGid: this.processGid,
30315
- umask: this.processUmask,
30316
- preserve: this.preservePaths,
30317
- unlink: this.unlink,
30318
- cwd: this.cwd,
30319
- mode
30320
- });
30321
- } catch (er) {
30322
- return er;
30323
- }
30324
- }
30325
- [LINK](entry, linkpath, link$1, done) {
30326
- const ls = `${link$1}Sync`;
30327
- try {
30328
- fs[ls](linkpath, String(entry.absolute));
30329
- done();
30330
- entry.resume();
30331
- } catch (er) {
30332
- return this[ONERROR](er, entry);
30333
- }
30334
- }
30335
- };
30336
-
30337
- //#endregion
30338
- //#region node_modules/tar/dist/esm/extract.js
30339
- const extractFileSync = (opt) => {
30340
- const u$2 = new UnpackSync(opt);
30341
- const file = opt.file;
30342
- const stat = fs.statSync(file);
30343
- const readSize = opt.maxReadSize || 16 * 1024 * 1024;
30344
- new ReadStreamSync(file, {
30345
- readSize,
30346
- size: stat.size
30347
- }).pipe(u$2);
30348
- };
30349
- const extractFile = (opt, _$2) => {
30350
- const u$2 = new Unpack(opt);
30351
- const readSize = opt.maxReadSize || 16 * 1024 * 1024;
30352
- const file = opt.file;
30353
- return new Promise((resolve$1, reject) => {
30354
- u$2.on("error", reject);
30355
- u$2.on("close", resolve$1);
30356
- fs.stat(file, (er, stat) => {
30357
- if (er) reject(er);
30358
- else {
30359
- const stream = new ReadStream(file, {
30360
- readSize,
30361
- size: stat.size
30362
- });
30363
- stream.on("error", reject);
30364
- stream.pipe(u$2);
30365
- }
30366
- });
30367
- });
30368
- };
30369
- const extract = makeCommand(extractFileSync, extractFile, (opt) => new UnpackSync(opt), (opt) => new Unpack(opt), (opt, files) => {
30370
- if (files?.length) filesFilter(opt, files);
30371
- });
30372
-
30373
- //#endregion
30374
- //#region node_modules/tar/dist/esm/replace.js
30375
- const replaceSync = (opt, files) => {
30376
- const p$1 = new PackSync(opt);
30377
- let threw = true;
30378
- let fd;
30379
- let position;
30380
- try {
30381
- try {
30382
- fd = fs.openSync(opt.file, "r+");
30383
- } catch (er) {
30384
- if (er?.code === "ENOENT") fd = fs.openSync(opt.file, "w+");
30385
- else throw er;
30386
- }
30387
- const st = fs.fstatSync(fd);
30388
- const headBuf = Buffer.alloc(512);
30389
- POSITION: for (position = 0; position < st.size; position += 512) {
30390
- for (let bufPos = 0, bytes = 0; bufPos < 512; bufPos += bytes) {
30391
- bytes = fs.readSync(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos);
30392
- if (position === 0 && headBuf[0] === 31 && headBuf[1] === 139) throw new Error("cannot append to compressed archives");
30393
- if (!bytes) break POSITION;
30394
- }
30395
- const h$2 = new Header(headBuf);
30396
- if (!h$2.cksumValid) break;
30397
- const entryBlockSize = 512 * Math.ceil((h$2.size || 0) / 512);
30398
- if (position + entryBlockSize + 512 > st.size) break;
30399
- position += entryBlockSize;
30400
- if (opt.mtimeCache && h$2.mtime) opt.mtimeCache.set(String(h$2.path), h$2.mtime);
30401
- }
30402
- threw = false;
30403
- streamSync(opt, p$1, position, fd, files);
30404
- } finally {
30405
- if (threw) try {
30406
- fs.closeSync(fd);
30407
- } catch (er) {}
30408
- }
30409
- };
30410
- const streamSync = (opt, p$1, position, fd, files) => {
30411
- const stream = new WriteStreamSync(opt.file, {
30412
- fd,
30413
- start: position
30414
- });
30415
- p$1.pipe(stream);
30416
- addFilesSync(p$1, files);
30417
- };
30418
- const replaceAsync = (opt, files) => {
30419
- files = Array.from(files);
30420
- const p$1 = new Pack(opt);
30421
- const getPos = (fd, size, cb_) => {
30422
- const cb = (er, pos$1) => {
30423
- if (er) fs.close(fd, (_$2) => cb_(er));
30424
- else cb_(null, pos$1);
30425
- };
30426
- let position = 0;
30427
- if (size === 0) return cb(null, 0);
30428
- let bufPos = 0;
30429
- const headBuf = Buffer.alloc(512);
30430
- const onread = (er, bytes) => {
30431
- if (er || typeof bytes === "undefined") return cb(er);
30432
- bufPos += bytes;
30433
- if (bufPos < 512 && bytes) return fs.read(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos, onread);
30434
- if (position === 0 && headBuf[0] === 31 && headBuf[1] === 139) return cb(/* @__PURE__ */ new Error("cannot append to compressed archives"));
30435
- if (bufPos < 512) return cb(null, position);
30436
- const h$2 = new Header(headBuf);
30437
- if (!h$2.cksumValid) return cb(null, position);
30438
- /* c8 ignore next */
30439
- const entryBlockSize = 512 * Math.ceil((h$2.size ?? 0) / 512);
30440
- if (position + entryBlockSize + 512 > size) return cb(null, position);
30441
- position += entryBlockSize + 512;
30442
- if (position >= size) return cb(null, position);
30443
- if (opt.mtimeCache && h$2.mtime) opt.mtimeCache.set(String(h$2.path), h$2.mtime);
30444
- bufPos = 0;
30445
- fs.read(fd, headBuf, 0, 512, position, onread);
30446
- };
30447
- fs.read(fd, headBuf, 0, 512, position, onread);
30448
- };
30449
- return new Promise((resolve$1, reject) => {
30450
- p$1.on("error", reject);
30451
- let flag = "r+";
30452
- const onopen = (er, fd) => {
30453
- if (er && er.code === "ENOENT" && flag === "r+") {
30454
- flag = "w+";
30455
- return fs.open(opt.file, flag, onopen);
30456
- }
30457
- if (er || !fd) return reject(er);
30458
- fs.fstat(fd, (er$1, st) => {
30459
- if (er$1) return fs.close(fd, () => reject(er$1));
30460
- getPos(fd, st.size, (er$2, position) => {
30461
- if (er$2) return reject(er$2);
30462
- const stream = new WriteStream(opt.file, {
30463
- fd,
30464
- start: position
30465
- });
30466
- p$1.pipe(stream);
30467
- stream.on("error", reject);
30468
- stream.on("close", resolve$1);
30469
- addFilesAsync(p$1, files);
30470
- });
30471
- });
30472
- };
30473
- fs.open(opt.file, flag, onopen);
30474
- });
30475
- };
30476
- const addFilesSync = (p$1, files) => {
30477
- files.forEach((file) => {
30478
- if (file.charAt(0) === "@") list({
30479
- file: path.resolve(p$1.cwd, file.slice(1)),
30480
- sync: true,
30481
- noResume: true,
30482
- onReadEntry: (entry) => p$1.add(entry)
30483
- });
30484
- else p$1.add(file);
30485
- });
30486
- p$1.end();
30487
- };
30488
- const addFilesAsync = async (p$1, files) => {
30489
- for (let i$1 = 0; i$1 < files.length; i$1++) {
30490
- const file = String(files[i$1]);
30491
- if (file.charAt(0) === "@") await list({
30492
- file: path.resolve(String(p$1.cwd), file.slice(1)),
30493
- noResume: true,
30494
- onReadEntry: (entry) => p$1.add(entry)
30495
- });
30496
- else p$1.add(file);
30497
- }
30498
- p$1.end();
30499
- };
30500
- const replace = makeCommand(
30501
- replaceSync,
30502
- replaceAsync,
30503
- /* c8 ignore start */
30504
- () => {
30505
- throw new TypeError("file is required");
30506
- },
30507
- () => {
30508
- throw new TypeError("file is required");
30509
- },
30510
- /* c8 ignore stop */
30511
- (opt, entries) => {
30512
- if (!isFile(opt)) throw new TypeError("file is required");
30513
- if (opt.gzip || opt.brotli || opt.zstd || opt.file.endsWith(".br") || opt.file.endsWith(".tbr")) throw new TypeError("cannot append to compressed archives");
30514
- if (!entries?.length) throw new TypeError("no paths specified to add/replace");
30515
- }
30516
- );
30517
-
30518
- //#endregion
30519
- //#region node_modules/tar/dist/esm/update.js
30520
- const update = makeCommand(replace.syncFile, replace.asyncFile, replace.syncNoFile, replace.asyncNoFile, (opt, entries = []) => {
30521
- replace.validate?.(opt, entries);
30522
- mtimeFilter(opt);
30523
- });
30524
- const mtimeFilter = (opt) => {
30525
- const filter = opt.filter;
30526
- if (!opt.mtimeCache) opt.mtimeCache = /* @__PURE__ */ new Map();
30527
- opt.filter = filter ? (path$17, stat) => filter(path$17, stat) && !((opt.mtimeCache?.get(path$17) ?? stat.mtime ?? 0) > (stat.mtime ?? 0)) : (path$17, stat) => !((opt.mtimeCache?.get(path$17) ?? stat.mtime ?? 0) > (stat.mtime ?? 0));
30528
- };
30529
-
30530
- //#endregion
30531
- //#region src/core/site/deploy.ts
30532
- async function deploySite(siteOutputDir) {
30533
- if (!await pathExists(siteOutputDir)) throw new Error(`Output directory does not exist: ${siteOutputDir}. Make sure to build your project first.`);
30534
- if ((await getSiteFilePaths(siteOutputDir)).length === 0) throw new Error(`No files found in output directory: ${siteOutputDir}. Make sure to build your project first.`);
30535
- const archivePath = join(tmpdir(), `base44-site-${getBase44ClientId()}-${randomUUID().toString()}.tar.gz`);
30536
- try {
30537
- await createArchive(siteOutputDir, archivePath);
30538
- return await uploadSite(archivePath);
30539
- } finally {
30540
- await deleteFile(archivePath);
30541
- }
30542
- }
30543
- async function createArchive(pathToArchive, targetArchivePath) {
30544
- await create({
30545
- gzip: true,
30546
- file: targetArchivePath,
30547
- cwd: pathToArchive
30548
- }, ["."]);
30549
- }
30550
-
30551
- //#endregion
30552
- //#region src/core/project/deploy.ts
30553
- /**
30554
- * Checks if there are any resources to deploy in the project.
30555
- *
30556
- * @param projectData - The project configuration and resources
30557
- * @returns true if there are entities, functions, or a configured site to deploy
30558
- */
30559
- function hasResourcesToDeploy(projectData) {
30560
- const { project, entities, functions } = projectData;
30561
- const hasSite = Boolean(project.site?.outputDirectory);
30562
- const hasEntities = entities.length > 0;
30563
- const hasFunctions = functions.length > 0;
30564
- return hasEntities || hasFunctions || hasSite;
30565
- }
30566
- /**
30567
- * Deploys all project resources (entities, functions, and site) to Base44.
30568
- *
30569
- * @param projectData - The project configuration and resources to deploy
30570
- * @returns The deployment result including app URL if site was deployed
30571
- */
30572
- async function deployAll(projectData) {
30573
- const { project, entities, functions } = projectData;
30574
- await entityResource.push(entities);
30575
- await functionResource.push(functions);
30576
- if (project.site?.outputDirectory) {
30577
- const { appUrl } = await deploySite(resolve(project.root, project.site.outputDirectory));
30578
- return { appUrl };
30579
- }
30580
- return {};
30581
- }
30582
-
30583
- //#endregion
30584
- //#region src/core/config.ts
30585
- const __dirname$1 = dirname(fileURLToPath(import.meta.url));
30586
- function getBase44GlobalDir() {
30587
- return join(homedir(), ".base44");
30588
- }
30589
- function getAuthFilePath() {
30590
- return join(getBase44GlobalDir(), "auth", "auth.json");
30591
- }
30592
- function getTemplatesDir() {
30593
- return join(__dirname$1, "templates");
30594
- }
30595
- function getTemplatesIndexPath() {
30596
- return join(getTemplatesDir(), "templates.json");
30597
- }
30598
- function getProjectEnvPath(projectRoot) {
30599
- return join(projectRoot, PROJECT_SUBDIR, ".env.local");
30600
- }
30601
- /**
30602
- * Load .env.local from the project root if it exists.
30603
- * Values won't override existing process.env variables.
30604
- */
30605
- async function loadProjectEnv(projectRoot) {
30606
- const found = projectRoot ? { root: projectRoot } : await findProjectRoot();
30607
- if (!found) return;
30608
- (0, import_main.config)({
30609
- path: getProjectEnvPath(found.root),
30610
- override: false,
30611
- quiet: true
30612
- });
30613
- }
30614
- function getBase44ApiUrl() {
30615
- return process.env.BASE44_API_URL || "https://app.base44.com";
30616
- }
30617
- function getBase44ClientId() {
30618
- return process.env.BASE44_CLIENT_ID;
30619
- }
30620
-
30621
- //#endregion
30622
- //#region src/core/clients/oauth-client.ts
30623
- /**
30624
- * HTTP client for OAuth endpoints.
30625
- * Used only for the login flow (device code, token exchange).
30626
- * These endpoints don't need Authorization headers - they use client_id + tokens in body.
30627
- */
30628
- const oauthClient = distribution_default.create({
30629
- prefixUrl: getBase44ApiUrl(),
30630
- headers: { "User-Agent": "Base44 CLI" }
30631
- });
30632
-
30633
- //#endregion
30634
- //#region src/core/auth/config.ts
30635
- const TOKEN_REFRESH_BUFFER_MS = 60 * 1e3;
30636
- let refreshPromise = null;
30637
- /**
30638
- * Reads and validates the stored authentication data.
30639
- *
30640
- * @returns The parsed authentication data (tokens, user info).
30641
- * @throws {Error} If not logged in or if auth data is corrupted.
30642
- *
30643
- * @example
30644
- * const auth = await readAuth();
30645
- * console.log(`Logged in as: ${auth.email}`);
30646
- */
30647
- async function readAuth() {
30648
- try {
30649
- const parsed = await readJsonFile(getAuthFilePath());
30650
- const result = AuthDataSchema.safeParse(parsed);
30651
- if (!result.success) throw new Error(`Invalid authentication data: ${result.error.issues.map((e$1) => e$1.message).join(", ")}`);
30652
- return result.data;
30653
- } catch (error) {
30654
- throw new Error(`Failed to read authentication file: ${error instanceof Error ? error.message : "Unknown error"}`);
30655
- }
30656
- }
30657
- async function writeAuth(authData) {
30658
- const result = AuthDataSchema.safeParse(authData);
30659
- if (!result.success) throw new Error(`Invalid authentication data: ${result.error.issues.map((e$1) => e$1.message).join(", ")}`);
30660
- try {
30661
- await writeJsonFile(getAuthFilePath(), result.data);
30662
- } catch (error) {
30663
- throw new Error(`Failed to write authentication file: ${error instanceof Error ? error.message : "Unknown error"}`);
30664
- }
30665
- }
30666
- async function deleteAuth() {
30667
- try {
30668
- await deleteFile(getAuthFilePath());
30669
- } catch (error) {
30670
- throw new Error(`Failed to delete authentication file: ${error instanceof Error ? error.message : "Unknown error"}`);
30671
- }
30672
- }
30673
- function isTokenExpired(auth) {
30674
- return Date.now() >= auth.expiresAt - TOKEN_REFRESH_BUFFER_MS;
30675
- }
30676
- async function refreshAndSaveTokens() {
30677
- if (refreshPromise) return refreshPromise;
30678
- refreshPromise = (async () => {
30679
- try {
30680
- const auth = await readAuth();
30681
- const tokenResponse = await renewAccessToken(auth.refreshToken);
30682
- await writeAuth({
30683
- ...auth,
30684
- accessToken: tokenResponse.accessToken,
30685
- refreshToken: tokenResponse.refreshToken,
30686
- expiresAt: Date.now() + tokenResponse.expiresIn * 1e3
30687
- });
30688
- return tokenResponse.accessToken;
30689
- } catch {
30690
- await deleteAuth();
30691
- return null;
30692
- } finally {
30693
- refreshPromise = null;
30694
- }
30695
- })();
30696
- return refreshPromise;
30697
- }
30698
- /**
30699
- * Checks if the user is currently logged in.
30700
- *
30701
- * @returns True if authentication data exists and is valid, false otherwise.
30702
- *
30703
- * @example
30704
- * if (await isLoggedIn()) {
30705
- * console.log("User is logged in");
30706
- * } else {
30707
- * console.log("Please login first");
30708
- * }
30709
- */
30710
- async function isLoggedIn() {
30711
- try {
30712
- await readAuth();
30713
- return true;
30714
- } catch {
30715
- return false;
30716
- }
30717
- }
30718
-
30719
- //#endregion
30720
- //#region src/core/clients/base44-client.ts
30721
- /**
30722
- * Authenticated HTTP client for Base44 API.
30723
- * Automatically handles token refresh and retry on 401 responses.
30724
- */
30725
- const retriedRequests = /* @__PURE__ */ new WeakSet();
30726
- /**
30727
- * Handles 401 responses by refreshing the token and retrying the request.
30728
- * Only retries once per request to prevent infinite loops.
30729
- */
30730
- async function handleUnauthorized(request, _options, response) {
30731
- if (response.status !== 401) return;
30732
- if (retriedRequests.has(request)) return;
30733
- const newAccessToken = await refreshAndSaveTokens();
30734
- if (!newAccessToken) return;
30735
- retriedRequests.add(request);
30736
- return distribution_default(request, { headers: { Authorization: `Bearer ${newAccessToken}` } });
30737
- }
30738
- /**
30739
- * Base44 API client with automatic authentication.
30740
- * Use this for general API calls that require authentication.
30741
- */
30742
- const base44Client = distribution_default.create({
30743
- prefixUrl: getBase44ApiUrl(),
30744
- headers: { "User-Agent": "Base44 CLI" },
30745
- hooks: {
30746
- beforeRequest: [async (request) => {
30747
- try {
30748
- const auth = await readAuth();
30749
- if (isTokenExpired(auth)) {
30750
- const newAccessToken = await refreshAndSaveTokens();
30751
- if (newAccessToken) {
30752
- request.headers.set("Authorization", `Bearer ${newAccessToken}`);
30753
- return;
30754
- }
30755
- }
30756
- request.headers.set("Authorization", `Bearer ${auth.accessToken}`);
30757
- } catch {}
30758
- }],
30759
- afterResponse: [handleUnauthorized]
30760
- }
30761
- });
30762
- /**
30763
- * Returns an HTTP client scoped to the current app.
30764
- * Use this for API calls to app-specific endpoints (entities, functions, etc.).
30765
- *
30766
- * @throws {Error} If BASE44_CLIENT_ID environment variable is not set.
30767
- *
30768
- * @example
30769
- * const appClient = getAppClient();
30770
- * const response = await appClient.get("entities");
30771
- */
30772
- function getAppClient() {
30773
- const clientId = getBase44ClientId();
30774
- if (!clientId) throw new Error("BASE44_CLIENT_ID environment variable is required. Set it in your .env.local file.");
30775
- return base44Client.extend({ prefixUrl: new URL(`/api/apps/${clientId}/`, getBase44ApiUrl()).href });
30776
- }
30777
-
30778
- //#endregion
30779
- //#region src/core/auth/api.ts
30780
- async function generateDeviceCode() {
30781
- const response = await oauthClient.post("oauth/device/code", {
30782
- json: {
30783
- client_id: AUTH_CLIENT_ID,
30784
- scope: "apps:read apps:write"
30785
- },
30786
- throwHttpErrors: false
30787
- });
30788
- if (!response.ok) throw new AuthApiError(`Failed to generate device code: ${response.status} ${response.statusText}`);
30789
- const result = DeviceCodeResponseSchema.safeParse(await response.json());
30790
- if (!result.success) throw new AuthValidationError(`Invalid device code response from server: ${result.error.message}`);
30791
- return result.data;
30792
- }
30793
- async function getTokenFromDeviceCode(deviceCode) {
30794
- const searchParams = new URLSearchParams();
30795
- searchParams.set("grant_type", "urn:ietf:params:oauth:grant-type:device_code");
30796
- searchParams.set("device_code", deviceCode);
30797
- searchParams.set("client_id", AUTH_CLIENT_ID);
30798
- const response = await oauthClient.post("oauth/token", {
30799
- body: searchParams.toString(),
30800
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
30801
- throwHttpErrors: false
30802
- });
30803
- const json = await response.json();
30804
- if (!response.ok) {
30805
- const errorResult = OAuthErrorSchema.safeParse(json);
30806
- if (!errorResult.success) throw new AuthValidationError(`Token request failed: ${errorResult.error.message}`);
30807
- const { error, error_description } = errorResult.data;
30808
- if (error === "authorization_pending" || error === "slow_down") return null;
30809
- throw new AuthApiError(error_description ?? `OAuth error: ${error}`);
30810
- }
30811
- const result = TokenResponseSchema.safeParse(json);
30812
- if (!result.success) throw new AuthValidationError(`Invalid token response from server: ${result.error.message}`);
30813
- return result.data;
30814
- }
30815
- async function renewAccessToken(refreshToken) {
30816
- const searchParams = new URLSearchParams();
30817
- searchParams.set("grant_type", "refresh_token");
30818
- searchParams.set("refresh_token", refreshToken);
30819
- searchParams.set("client_id", AUTH_CLIENT_ID);
30820
- const response = await oauthClient.post("oauth/token", {
30821
- body: searchParams.toString(),
30822
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
30823
- throwHttpErrors: false
30824
- });
30825
- const json = await response.json();
30826
- if (!response.ok) {
30827
- const errorResult = OAuthErrorSchema.safeParse(json);
30828
- if (!errorResult.success) throw new AuthApiError(`Token refresh failed: ${response.statusText}`);
30829
- const { error, error_description } = errorResult.data;
30830
- throw new AuthApiError(error_description ?? `OAuth error: ${error}`);
30831
- }
30832
- const result = TokenResponseSchema.safeParse(json);
30833
- if (!result.success) throw new AuthValidationError(`Invalid token response from server: ${result.error.message}`);
30834
- return result.data;
30835
- }
30836
- async function getUserInfo(accessToken) {
30837
- const response = await oauthClient.get("oauth/userinfo", { headers: { Authorization: `Bearer ${accessToken}` } });
30838
- if (!response.ok) throw new AuthApiError(`Failed to fetch user info: ${response.status}`);
30839
- const result = UserInfoSchema.safeParse(await response.json());
30840
- if (!result.success) throw new AuthValidationError(`Invalid UserInfo response from server: ${result.error.message}`);
30841
- return result.data;
30842
- }
30843
-
30844
- //#endregion
30845
- //#region node_modules/chalk/source/vendor/ansi-styles/index.js
30846
- const ANSI_BACKGROUND_OFFSET = 10;
30847
- const wrapAnsi16 = (offset = 0) => (code$1) => `\u001B[${code$1 + offset}m`;
30848
- const wrapAnsi256 = (offset = 0) => (code$1) => `\u001B[${38 + offset};5;${code$1}m`;
30849
- const wrapAnsi16m = (offset = 0) => (red$1, green$1, blue$1) => `\u001B[${38 + offset};2;${red$1};${green$1};${blue$1}m`;
30850
- const styles$1 = {
30851
- modifier: {
30852
- reset: [0, 0],
30853
- bold: [1, 22],
30854
- dim: [2, 22],
30855
- italic: [3, 23],
30856
- underline: [4, 24],
30857
- overline: [53, 55],
30858
- inverse: [7, 27],
30859
- hidden: [8, 28],
30860
- strikethrough: [9, 29]
30861
- },
30862
- color: {
30863
- black: [30, 39],
30864
- red: [31, 39],
30865
- green: [32, 39],
30866
- yellow: [33, 39],
30867
- blue: [34, 39],
30868
- magenta: [35, 39],
30869
- cyan: [36, 39],
30870
- white: [37, 39],
30871
- blackBright: [90, 39],
30872
- gray: [90, 39],
30873
- grey: [90, 39],
30874
- redBright: [91, 39],
30875
- greenBright: [92, 39],
30876
- yellowBright: [93, 39],
30877
- blueBright: [94, 39],
30878
- magentaBright: [95, 39],
30879
- cyanBright: [96, 39],
30880
- whiteBright: [97, 39]
30881
- },
30882
- bgColor: {
30883
- bgBlack: [40, 49],
30884
- bgRed: [41, 49],
30885
- bgGreen: [42, 49],
30886
- bgYellow: [43, 49],
30887
- bgBlue: [44, 49],
30888
- bgMagenta: [45, 49],
30889
- bgCyan: [46, 49],
30890
- bgWhite: [47, 49],
30891
- bgBlackBright: [100, 49],
30892
- bgGray: [100, 49],
30893
- bgGrey: [100, 49],
30894
- bgRedBright: [101, 49],
30895
- bgGreenBright: [102, 49],
30896
- bgYellowBright: [103, 49],
30897
- bgBlueBright: [104, 49],
30898
- bgMagentaBright: [105, 49],
30899
- bgCyanBright: [106, 49],
30900
- bgWhiteBright: [107, 49]
30901
- }
30902
- };
30903
- const modifierNames = Object.keys(styles$1.modifier);
30904
- const foregroundColorNames = Object.keys(styles$1.color);
30905
- const backgroundColorNames = Object.keys(styles$1.bgColor);
30906
- const colorNames = [...foregroundColorNames, ...backgroundColorNames];
30907
- function assembleStyles() {
30908
- const codes = /* @__PURE__ */ new Map();
30909
- for (const [groupName, group] of Object.entries(styles$1)) {
30910
- for (const [styleName, style] of Object.entries(group)) {
30911
- styles$1[styleName] = {
30912
- open: `\u001B[${style[0]}m`,
30913
- close: `\u001B[${style[1]}m`
30914
- };
30915
- group[styleName] = styles$1[styleName];
30916
- codes.set(style[0], style[1]);
30917
- }
30918
- Object.defineProperty(styles$1, groupName, {
30919
- value: group,
30920
- enumerable: false
30921
- });
30922
- }
30923
- Object.defineProperty(styles$1, "codes", {
30924
- value: codes,
30925
- enumerable: false
30926
- });
30927
- styles$1.color.close = "\x1B[39m";
30928
- styles$1.bgColor.close = "\x1B[49m";
30929
- styles$1.color.ansi = wrapAnsi16();
30930
- styles$1.color.ansi256 = wrapAnsi256();
30931
- styles$1.color.ansi16m = wrapAnsi16m();
30932
- styles$1.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
30933
- styles$1.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
30934
- styles$1.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
30935
- Object.defineProperties(styles$1, {
30936
- rgbToAnsi256: {
30937
- value(red$1, green$1, blue$1) {
30938
- if (red$1 === green$1 && green$1 === blue$1) {
30939
- if (red$1 < 8) return 16;
30940
- if (red$1 > 248) return 231;
30941
- return Math.round((red$1 - 8) / 247 * 24) + 232;
30942
- }
30943
- return 16 + 36 * Math.round(red$1 / 255 * 5) + 6 * Math.round(green$1 / 255 * 5) + Math.round(blue$1 / 255 * 5);
30944
- },
30945
- enumerable: false
30946
- },
30947
- hexToRgb: {
30948
- value(hex) {
30949
- const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
30950
- if (!matches) return [
30951
- 0,
30952
- 0,
30953
- 0
30954
- ];
30955
- let [colorString] = matches;
30956
- if (colorString.length === 3) colorString = [...colorString].map((character) => character + character).join("");
30957
- const integer$1 = Number.parseInt(colorString, 16);
30958
- return [
30959
- integer$1 >> 16 & 255,
30960
- integer$1 >> 8 & 255,
30961
- integer$1 & 255
30962
- ];
30963
- },
30964
- enumerable: false
30965
- },
30966
- hexToAnsi256: {
30967
- value: (hex) => styles$1.rgbToAnsi256(...styles$1.hexToRgb(hex)),
30968
- enumerable: false
30969
- },
30970
- ansi256ToAnsi: {
30971
- value(code$1) {
30972
- if (code$1 < 8) return 30 + code$1;
30973
- if (code$1 < 16) return 90 + (code$1 - 8);
30974
- let red$1;
30975
- let green$1;
30976
- let blue$1;
30977
- if (code$1 >= 232) {
30978
- red$1 = ((code$1 - 232) * 10 + 8) / 255;
30979
- green$1 = red$1;
30980
- blue$1 = red$1;
30981
- } else {
30982
- code$1 -= 16;
30983
- const remainder = code$1 % 36;
30984
- red$1 = Math.floor(code$1 / 36) / 5;
30985
- green$1 = Math.floor(remainder / 6) / 5;
30986
- blue$1 = remainder % 6 / 5;
30987
- }
30988
- const value = Math.max(red$1, green$1, blue$1) * 2;
30989
- if (value === 0) return 30;
30990
- let result = 30 + (Math.round(blue$1) << 2 | Math.round(green$1) << 1 | Math.round(red$1));
30991
- if (value === 2) result += 60;
30992
- return result;
30993
- },
30994
- enumerable: false
30995
- },
30996
- rgbToAnsi: {
30997
- value: (red$1, green$1, blue$1) => styles$1.ansi256ToAnsi(styles$1.rgbToAnsi256(red$1, green$1, blue$1)),
30998
- enumerable: false
30999
- },
31000
- hexToAnsi: {
31001
- value: (hex) => styles$1.ansi256ToAnsi(styles$1.hexToAnsi256(hex)),
31002
- enumerable: false
30991
+ const fd = stream.fd;
30992
+ if (typeof fd === "number" && entry.mtime && !this.noMtime) {
30993
+ actions++;
30994
+ const atime = entry.atime || /* @__PURE__ */ new Date();
30995
+ const mtime = entry.mtime;
30996
+ fs.futimes(fd, atime, mtime, (er) => er ? fs.utimes(abs, atime, mtime, (er2) => done(er2 && er)) : done());
30997
+ }
30998
+ if (typeof fd === "number" && this[DOCHOWN](entry)) {
30999
+ actions++;
31000
+ const uid = this[UID](entry);
31001
+ const gid = this[GID](entry);
31002
+ if (typeof uid === "number" && typeof gid === "number") fs.fchown(fd, uid, gid, (er) => er ? fs.chown(abs, uid, gid, (er2) => done(er2 && er)) : done());
31003
+ }
31004
+ done();
31005
+ });
31006
+ const tx = this.transform ? this.transform(entry) || entry : entry;
31007
+ if (tx !== entry) {
31008
+ tx.on("error", (er) => {
31009
+ this[ONERROR](er, entry);
31010
+ fullyDone();
31011
+ });
31012
+ entry.pipe(tx);
31003
31013
  }
31004
- });
31005
- return styles$1;
31006
- }
31007
- const ansiStyles = assembleStyles();
31008
- var ansi_styles_default = ansiStyles;
31009
-
31010
- //#endregion
31011
- //#region node_modules/chalk/source/vendor/supports-color/index.js
31012
- function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process$1.argv) {
31013
- const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
31014
- const position = argv.indexOf(prefix + flag);
31015
- const terminatorPosition = argv.indexOf("--");
31016
- return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
31017
- }
31018
- const { env } = process$1;
31019
- let flagForceColor;
31020
- if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) flagForceColor = 0;
31021
- else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) flagForceColor = 1;
31022
- function envForceColor() {
31023
- if ("FORCE_COLOR" in env) {
31024
- if (env.FORCE_COLOR === "true") return 1;
31025
- if (env.FORCE_COLOR === "false") return 0;
31026
- return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
31014
+ tx.pipe(stream);
31027
31015
  }
31028
- }
31029
- function translateLevel(level) {
31030
- if (level === 0) return false;
31031
- return {
31032
- level,
31033
- hasBasic: true,
31034
- has256: level >= 2,
31035
- has16m: level >= 3
31036
- };
31037
- }
31038
- function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
31039
- const noFlagForceColor = envForceColor();
31040
- if (noFlagForceColor !== void 0) flagForceColor = noFlagForceColor;
31041
- const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
31042
- if (forceColor === 0) return 0;
31043
- if (sniffFlags) {
31044
- if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) return 3;
31045
- if (hasFlag("color=256")) return 2;
31016
+ [DIRECTORY](entry, fullyDone) {
31017
+ const mode = typeof entry.mode === "number" ? entry.mode & 4095 : this.dmode;
31018
+ this[MKDIR](String(entry.absolute), mode, (er) => {
31019
+ if (er) {
31020
+ this[ONERROR](er, entry);
31021
+ fullyDone();
31022
+ return;
31023
+ }
31024
+ let actions = 1;
31025
+ const done = () => {
31026
+ if (--actions === 0) {
31027
+ fullyDone();
31028
+ this[UNPEND]();
31029
+ entry.resume();
31030
+ }
31031
+ };
31032
+ if (entry.mtime && !this.noMtime) {
31033
+ actions++;
31034
+ fs.utimes(String(entry.absolute), entry.atime || /* @__PURE__ */ new Date(), entry.mtime, done);
31035
+ }
31036
+ if (this[DOCHOWN](entry)) {
31037
+ actions++;
31038
+ fs.chown(String(entry.absolute), Number(this[UID](entry)), Number(this[GID](entry)), done);
31039
+ }
31040
+ done();
31041
+ });
31046
31042
  }
31047
- if ("TF_BUILD" in env && "AGENT_NAME" in env) return 1;
31048
- if (haveStream && !streamIsTTY && forceColor === void 0) return 0;
31049
- const min = forceColor || 0;
31050
- if (env.TERM === "dumb") return min;
31051
- if (process$1.platform === "win32") {
31052
- const osRelease = os.release().split(".");
31053
- if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
31054
- return 1;
31043
+ [UNSUPPORTED](entry) {
31044
+ entry.unsupported = true;
31045
+ this.warn("TAR_ENTRY_UNSUPPORTED", `unsupported entry type: ${entry.type}`, { entry });
31046
+ entry.resume();
31055
31047
  }
31056
- if ("CI" in env) {
31057
- if ([
31058
- "GITHUB_ACTIONS",
31059
- "GITEA_ACTIONS",
31060
- "CIRCLECI"
31061
- ].some((key) => key in env)) return 3;
31062
- if ([
31063
- "TRAVIS",
31064
- "APPVEYOR",
31065
- "GITLAB_CI",
31066
- "BUILDKITE",
31067
- "DRONE"
31068
- ].some((sign) => sign in env) || env.CI_NAME === "codeship") return 1;
31069
- return min;
31048
+ [SYMLINK](entry, done) {
31049
+ this[LINK](entry, String(entry.linkpath), "symlink", done);
31070
31050
  }
31071
- if ("TEAMCITY_VERSION" in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
31072
- if (env.COLORTERM === "truecolor") return 3;
31073
- if (env.TERM === "xterm-kitty") return 3;
31074
- if (env.TERM === "xterm-ghostty") return 3;
31075
- if (env.TERM === "wezterm") return 3;
31076
- if ("TERM_PROGRAM" in env) {
31077
- const version$2 = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
31078
- switch (env.TERM_PROGRAM) {
31079
- case "iTerm.app": return version$2 >= 3 ? 3 : 2;
31080
- case "Apple_Terminal": return 2;
31081
- }
31051
+ [HARDLINK](entry, done) {
31052
+ const linkpath = normalizeWindowsPath(path.resolve(this.cwd, String(entry.linkpath)));
31053
+ this[LINK](entry, linkpath, "link", done);
31082
31054
  }
31083
- if (/-256(color)?$/i.test(env.TERM)) return 2;
31084
- if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) return 1;
31085
- if ("COLORTERM" in env) return 1;
31086
- return min;
31087
- }
31088
- function createSupportsColor(stream, options = {}) {
31089
- return translateLevel(_supportsColor(stream, {
31090
- streamIsTTY: stream && stream.isTTY,
31091
- ...options
31092
- }));
31093
- }
31094
- const supportsColor = {
31095
- stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
31096
- stderr: createSupportsColor({ isTTY: tty.isatty(2) })
31097
- };
31098
- var supports_color_default = supportsColor;
31099
-
31100
- //#endregion
31101
- //#region node_modules/chalk/source/utilities.js
31102
- function stringReplaceAll(string$2, substring, replacer) {
31103
- let index = string$2.indexOf(substring);
31104
- if (index === -1) return string$2;
31105
- const substringLength = substring.length;
31106
- let endIndex = 0;
31107
- let returnValue = "";
31108
- do {
31109
- returnValue += string$2.slice(endIndex, index) + substring + replacer;
31110
- endIndex = index + substringLength;
31111
- index = string$2.indexOf(substring, endIndex);
31112
- } while (index !== -1);
31113
- returnValue += string$2.slice(endIndex);
31114
- return returnValue;
31115
- }
31116
- function stringEncaseCRLFWithFirstIndex(string$2, prefix, postfix, index) {
31117
- let endIndex = 0;
31118
- let returnValue = "";
31119
- do {
31120
- const gotCR = string$2[index - 1] === "\r";
31121
- returnValue += string$2.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
31122
- endIndex = index + 1;
31123
- index = string$2.indexOf("\n", endIndex);
31124
- } while (index !== -1);
31125
- returnValue += string$2.slice(endIndex);
31126
- return returnValue;
31127
- }
31128
-
31129
- //#endregion
31130
- //#region node_modules/chalk/source/index.js
31131
- const { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
31132
- const GENERATOR = Symbol("GENERATOR");
31133
- const STYLER = Symbol("STYLER");
31134
- const IS_EMPTY = Symbol("IS_EMPTY");
31135
- const levelMapping = [
31136
- "ansi",
31137
- "ansi",
31138
- "ansi256",
31139
- "ansi16m"
31140
- ];
31141
- const styles = Object.create(null);
31142
- const applyOptions = (object$1, options = {}) => {
31143
- if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) throw new Error("The `level` option should be an integer from 0 to 3");
31144
- const colorLevel = stdoutColor ? stdoutColor.level : 0;
31145
- object$1.level = options.level === void 0 ? colorLevel : options.level;
31146
- };
31147
- const chalkFactory = (options) => {
31148
- const chalk$1 = (...strings) => strings.join(" ");
31149
- applyOptions(chalk$1, options);
31150
- Object.setPrototypeOf(chalk$1, createChalk.prototype);
31151
- return chalk$1;
31152
- };
31153
- function createChalk(options) {
31154
- return chalkFactory(options);
31155
- }
31156
- Object.setPrototypeOf(createChalk.prototype, Function.prototype);
31157
- for (const [styleName, style] of Object.entries(ansi_styles_default)) styles[styleName] = { get() {
31158
- const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
31159
- Object.defineProperty(this, styleName, { value: builder });
31160
- return builder;
31161
- } };
31162
- styles.visible = { get() {
31163
- const builder = createBuilder(this, this[STYLER], true);
31164
- Object.defineProperty(this, "visible", { value: builder });
31165
- return builder;
31166
- } };
31167
- const getModelAnsi = (model, level, type, ...arguments_) => {
31168
- if (model === "rgb") {
31169
- if (level === "ansi16m") return ansi_styles_default[type].ansi16m(...arguments_);
31170
- if (level === "ansi256") return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
31171
- return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
31055
+ [PEND]() {
31056
+ this[PENDING]++;
31172
31057
  }
31173
- if (model === "hex") return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
31174
- return ansi_styles_default[type][model](...arguments_);
31175
- };
31176
- for (const model of [
31177
- "rgb",
31178
- "hex",
31179
- "ansi256"
31180
- ]) {
31181
- styles[model] = { get() {
31182
- const { level } = this;
31183
- return function(...arguments_) {
31184
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
31185
- return createBuilder(this, styler, this[IS_EMPTY]);
31058
+ [UNPEND]() {
31059
+ this[PENDING]--;
31060
+ this[MAYBECLOSE]();
31061
+ }
31062
+ [SKIP](entry) {
31063
+ this[UNPEND]();
31064
+ entry.resume();
31065
+ }
31066
+ [ISREUSABLE](entry, st) {
31067
+ return entry.type === "File" && !this.unlink && st.isFile() && st.nlink <= 1 && !isWindows;
31068
+ }
31069
+ [CHECKFS](entry) {
31070
+ this[PEND]();
31071
+ const paths = [entry.path];
31072
+ if (entry.linkpath) paths.push(entry.linkpath);
31073
+ this.reservations.reserve(paths, (done) => this[CHECKFS2](entry, done));
31074
+ }
31075
+ [CHECKFS2](entry, fullyDone) {
31076
+ const done = (er) => {
31077
+ fullyDone(er);
31186
31078
  };
31187
- } };
31188
- const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
31189
- styles[bgModel] = { get() {
31190
- const { level } = this;
31191
- return function(...arguments_) {
31192
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
31193
- return createBuilder(this, styler, this[IS_EMPTY]);
31079
+ const checkCwd$1 = () => {
31080
+ this[MKDIR](this.cwd, this.dmode, (er) => {
31081
+ if (er) {
31082
+ this[ONERROR](er, entry);
31083
+ done();
31084
+ return;
31085
+ }
31086
+ this[CHECKED_CWD] = true;
31087
+ start();
31088
+ });
31194
31089
  };
31195
- } };
31196
- }
31197
- const proto = Object.defineProperties(() => {}, {
31198
- ...styles,
31199
- level: {
31200
- enumerable: true,
31201
- get() {
31202
- return this[GENERATOR].level;
31203
- },
31204
- set(level) {
31205
- this[GENERATOR].level = level;
31090
+ const start = () => {
31091
+ if (entry.absolute !== this.cwd) {
31092
+ const parent = normalizeWindowsPath(path.dirname(String(entry.absolute)));
31093
+ if (parent !== this.cwd) return this[MKDIR](parent, this.dmode, (er) => {
31094
+ if (er) {
31095
+ this[ONERROR](er, entry);
31096
+ done();
31097
+ return;
31098
+ }
31099
+ afterMakeParent();
31100
+ });
31101
+ }
31102
+ afterMakeParent();
31103
+ };
31104
+ const afterMakeParent = () => {
31105
+ fs.lstat(String(entry.absolute), (lstatEr, st) => {
31106
+ if (st && (this.keep || this.newer && st.mtime > (entry.mtime ?? st.mtime))) {
31107
+ this[SKIP](entry);
31108
+ done();
31109
+ return;
31110
+ }
31111
+ if (lstatEr || this[ISREUSABLE](entry, st)) return this[MAKEFS](null, entry, done);
31112
+ if (st.isDirectory()) {
31113
+ if (entry.type === "Directory") {
31114
+ const needChmod = this.chmod && entry.mode && (st.mode & 4095) !== entry.mode;
31115
+ const afterChmod = (er) => this[MAKEFS](er ?? null, entry, done);
31116
+ if (!needChmod) return afterChmod();
31117
+ return fs.chmod(String(entry.absolute), Number(entry.mode), afterChmod);
31118
+ }
31119
+ if (entry.absolute !== this.cwd) return fs.rmdir(String(entry.absolute), (er) => this[MAKEFS](er ?? null, entry, done));
31120
+ }
31121
+ if (entry.absolute === this.cwd) return this[MAKEFS](null, entry, done);
31122
+ unlinkFile(String(entry.absolute), (er) => this[MAKEFS](er ?? null, entry, done));
31123
+ });
31124
+ };
31125
+ if (this[CHECKED_CWD]) start();
31126
+ else checkCwd$1();
31127
+ }
31128
+ [MAKEFS](er, entry, done) {
31129
+ if (er) {
31130
+ this[ONERROR](er, entry);
31131
+ done();
31132
+ return;
31133
+ }
31134
+ switch (entry.type) {
31135
+ case "File":
31136
+ case "OldFile":
31137
+ case "ContiguousFile": return this[FILE](entry, done);
31138
+ case "Link": return this[HARDLINK](entry, done);
31139
+ case "SymbolicLink": return this[SYMLINK](entry, done);
31140
+ case "Directory":
31141
+ case "GNUDumpDir": return this[DIRECTORY](entry, done);
31206
31142
  }
31207
31143
  }
31208
- });
31209
- const createStyler = (open$1, close, parent) => {
31210
- let openAll;
31211
- let closeAll;
31212
- if (parent === void 0) {
31213
- openAll = open$1;
31214
- closeAll = close;
31215
- } else {
31216
- openAll = parent.openAll + open$1;
31217
- closeAll = close + parent.closeAll;
31144
+ [LINK](entry, linkpath, link$1, done) {
31145
+ fs[link$1](linkpath, String(entry.absolute), (er) => {
31146
+ if (er) this[ONERROR](er, entry);
31147
+ else {
31148
+ this[UNPEND]();
31149
+ entry.resume();
31150
+ }
31151
+ done();
31152
+ });
31218
31153
  }
31219
- return {
31220
- open: open$1,
31221
- close,
31222
- openAll,
31223
- closeAll,
31224
- parent
31225
- };
31226
- };
31227
- const createBuilder = (self$1, _styler, _isEmpty) => {
31228
- const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
31229
- Object.setPrototypeOf(builder, proto);
31230
- builder[GENERATOR] = self$1;
31231
- builder[STYLER] = _styler;
31232
- builder[IS_EMPTY] = _isEmpty;
31233
- return builder;
31234
31154
  };
31235
- const applyStyle = (self$1, string$2) => {
31236
- if (self$1.level <= 0 || !string$2) return self$1[IS_EMPTY] ? "" : string$2;
31237
- let styler = self$1[STYLER];
31238
- if (styler === void 0) return string$2;
31239
- const { openAll, closeAll } = styler;
31240
- if (string$2.includes("\x1B")) while (styler !== void 0) {
31241
- string$2 = stringReplaceAll(string$2, styler.close, styler.open);
31242
- styler = styler.parent;
31155
+ const callSync = (fn) => {
31156
+ try {
31157
+ return [null, fn()];
31158
+ } catch (er) {
31159
+ return [er, null];
31243
31160
  }
31244
- const lfIndex = string$2.indexOf("\n");
31245
- if (lfIndex !== -1) string$2 = stringEncaseCRLFWithFirstIndex(string$2, closeAll, openAll, lfIndex);
31246
- return openAll + string$2 + closeAll;
31247
31161
  };
31248
- Object.defineProperties(createChalk.prototype, styles);
31249
- const chalk = createChalk();
31250
- const chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
31251
- var source_default = chalk;
31252
-
31253
- //#endregion
31254
- //#region src/cli/utils/theme.ts
31255
- /**
31256
- * Base44 CLI theme configuration
31257
- */
31258
- const theme = {
31259
- colors: {
31260
- base44Orange: source_default.hex("#E86B3C"),
31261
- base44OrangeBackground: source_default.bgHex("#E86B3C"),
31262
- shinyOrange: source_default.hex("#FFD700"),
31263
- links: source_default.hex("#00D4FF"),
31264
- white: source_default.white
31265
- },
31266
- styles: {
31267
- header: source_default.dim,
31268
- bold: source_default.bold,
31269
- dim: source_default.dim
31162
+ var UnpackSync = class extends Unpack {
31163
+ sync = true;
31164
+ [MAKEFS](er, entry) {
31165
+ return super[MAKEFS](er, entry, () => {});
31270
31166
  }
31271
- };
31272
-
31273
- //#endregion
31274
- //#region src/cli/utils/animate.ts
31275
- /**
31276
- * Sleep for a specified number of milliseconds.
31277
- */
31278
- function sleep(ms) {
31279
- return new Promise((resolve$1) => setTimeout(resolve$1, ms));
31280
- }
31281
- /**
31282
- * Animate a single line with a left-to-right color reveal.
31283
- */
31284
- async function animateLineReveal(line, duration$2) {
31285
- const steps = 8;
31286
- const stepDuration = duration$2 / steps;
31287
- for (let step = 0; step <= steps; step++) {
31288
- const progress = step / steps;
31289
- const revealIndex = Math.floor(progress * line.length);
31290
- let output = "";
31291
- for (let i$1 = 0; i$1 < line.length; i$1++) if (i$1 < revealIndex) output += theme.colors.base44Orange(line[i$1]);
31292
- else if (i$1 === revealIndex) output += theme.colors.shinyOrange(line[i$1]);
31293
- else output += theme.styles.dim(line[i$1]);
31294
- process.stdout.write(`\r${output}`);
31295
- await sleep(stepDuration);
31167
+ [CHECKFS](entry) {
31168
+ if (!this[CHECKED_CWD]) {
31169
+ const er$1 = this[MKDIR](this.cwd, this.dmode);
31170
+ if (er$1) return this[ONERROR](er$1, entry);
31171
+ this[CHECKED_CWD] = true;
31172
+ }
31173
+ if (entry.absolute !== this.cwd) {
31174
+ const parent = normalizeWindowsPath(path.dirname(String(entry.absolute)));
31175
+ if (parent !== this.cwd) {
31176
+ const mkParent = this[MKDIR](parent, this.dmode);
31177
+ if (mkParent) return this[ONERROR](mkParent, entry);
31178
+ }
31179
+ }
31180
+ const [lstatEr, st] = callSync(() => fs.lstatSync(String(entry.absolute)));
31181
+ if (st && (this.keep || this.newer && st.mtime > (entry.mtime ?? st.mtime))) return this[SKIP](entry);
31182
+ if (lstatEr || this[ISREUSABLE](entry, st)) return this[MAKEFS](null, entry);
31183
+ if (st.isDirectory()) {
31184
+ if (entry.type === "Directory") {
31185
+ const [er$2] = this.chmod && entry.mode && (st.mode & 4095) !== entry.mode ? callSync(() => {
31186
+ fs.chmodSync(String(entry.absolute), Number(entry.mode));
31187
+ }) : [];
31188
+ return this[MAKEFS](er$2, entry);
31189
+ }
31190
+ const [er$1] = callSync(() => fs.rmdirSync(String(entry.absolute)));
31191
+ this[MAKEFS](er$1, entry);
31192
+ }
31193
+ const [er] = entry.absolute === this.cwd ? [] : callSync(() => unlinkFileSync(String(entry.absolute)));
31194
+ this[MAKEFS](er, entry);
31296
31195
  }
31297
- process.stdout.write(`\r${theme.colors.base44Orange(line)}\n`);
31298
- }
31299
- /**
31300
- * Quick shimmer pass over the entire banner.
31301
- */
31302
- async function shimmerPass(lines, duration$2) {
31303
- const moveUp = `\x1b[${lines.length}A`;
31304
- const steps = 12;
31305
- const stepDuration = duration$2 / steps;
31306
- const maxWidth = Math.max(...lines.map((l$1) => l$1.length));
31307
- for (let step = 0; step <= steps; step++) {
31308
- const shimmerPos = Math.floor(step / steps * (maxWidth + 6));
31309
- process.stdout.write(moveUp);
31310
- for (const line of lines) {
31311
- let output = "";
31312
- for (let i$1 = 0; i$1 < line.length; i$1++) {
31313
- const dist = Math.abs(i$1 - shimmerPos);
31314
- if (dist < 3) output += dist === 0 ? theme.colors.white(line[i$1]) : theme.colors.shinyOrange(line[i$1]);
31315
- else output += theme.colors.base44Orange(line[i$1]);
31196
+ [FILE](entry, done) {
31197
+ const mode = typeof entry.mode === "number" ? entry.mode & 4095 : this.fmode;
31198
+ const oner = (er) => {
31199
+ let closeError;
31200
+ try {
31201
+ fs.closeSync(fd);
31202
+ } catch (e$1) {
31203
+ closeError = e$1;
31204
+ }
31205
+ if (er || closeError) this[ONERROR](er || closeError, entry);
31206
+ done();
31207
+ };
31208
+ let fd;
31209
+ try {
31210
+ fd = fs.openSync(String(entry.absolute), getWriteFlag(entry.size), mode);
31211
+ } catch (er) {
31212
+ return oner(er);
31213
+ }
31214
+ /* c8 ignore stop */
31215
+ const tx = this.transform ? this.transform(entry) || entry : entry;
31216
+ if (tx !== entry) {
31217
+ tx.on("error", (er) => this[ONERROR](er, entry));
31218
+ entry.pipe(tx);
31219
+ }
31220
+ tx.on("data", (chunk) => {
31221
+ try {
31222
+ fs.writeSync(fd, chunk, 0, chunk.length);
31223
+ } catch (er) {
31224
+ oner(er);
31316
31225
  }
31317
- console.log(output);
31226
+ });
31227
+ tx.on("end", () => {
31228
+ let er = null;
31229
+ if (entry.mtime && !this.noMtime) {
31230
+ const atime = entry.atime || /* @__PURE__ */ new Date();
31231
+ const mtime = entry.mtime;
31232
+ try {
31233
+ fs.futimesSync(fd, atime, mtime);
31234
+ } catch (futimeser) {
31235
+ try {
31236
+ fs.utimesSync(String(entry.absolute), atime, mtime);
31237
+ } catch (utimeser) {
31238
+ er = futimeser;
31239
+ }
31240
+ }
31241
+ }
31242
+ if (this[DOCHOWN](entry)) {
31243
+ const uid = this[UID](entry);
31244
+ const gid = this[GID](entry);
31245
+ try {
31246
+ fs.fchownSync(fd, Number(uid), Number(gid));
31247
+ } catch (fchowner) {
31248
+ try {
31249
+ fs.chownSync(String(entry.absolute), Number(uid), Number(gid));
31250
+ } catch (chowner) {
31251
+ er = er || fchowner;
31252
+ }
31253
+ }
31254
+ }
31255
+ oner(er);
31256
+ });
31257
+ }
31258
+ [DIRECTORY](entry, done) {
31259
+ const mode = typeof entry.mode === "number" ? entry.mode & 4095 : this.dmode;
31260
+ const er = this[MKDIR](String(entry.absolute), mode);
31261
+ if (er) {
31262
+ this[ONERROR](er, entry);
31263
+ done();
31264
+ return;
31318
31265
  }
31319
- await sleep(stepDuration);
31266
+ if (entry.mtime && !this.noMtime) try {
31267
+ fs.utimesSync(String(entry.absolute), entry.atime || /* @__PURE__ */ new Date(), entry.mtime);
31268
+ } catch (er$1) {}
31269
+ if (this[DOCHOWN](entry)) try {
31270
+ fs.chownSync(String(entry.absolute), Number(this[UID](entry)), Number(this[GID](entry)));
31271
+ } catch (er$1) {}
31272
+ done();
31273
+ entry.resume();
31320
31274
  }
31321
- process.stdout.write(moveUp);
31322
- for (const line of lines) console.log(theme.colors.base44Orange(line));
31323
- }
31324
- /**
31325
- * Animate the output with a smooth line-by-line reveal.
31326
- * Each line fades in with a gradient sweep effect.
31327
- *
31328
- * Total duration: ~1.5 seconds for a magical but not slow feel.
31329
- */
31330
- async function printAnimatedLines(lines) {
31331
- const lineDelay = 1e3 / lines.length;
31332
- for (let i$1 = 0; i$1 < lines.length; i$1++) {
31333
- const line = lines[i$1];
31334
- await animateLineReveal(line, 100);
31335
- if (i$1 < lines.length - 1) await sleep(lineDelay - 100);
31275
+ [MKDIR](dir, mode) {
31276
+ try {
31277
+ return mkdirSync(normalizeWindowsPath(dir), {
31278
+ uid: this.uid,
31279
+ gid: this.gid,
31280
+ processUid: this.processUid,
31281
+ processGid: this.processGid,
31282
+ umask: this.processUmask,
31283
+ preserve: this.preservePaths,
31284
+ unlink: this.unlink,
31285
+ cwd: this.cwd,
31286
+ mode
31287
+ });
31288
+ } catch (er) {
31289
+ return er;
31290
+ }
31336
31291
  }
31337
- await shimmerPass(lines, 200);
31338
- }
31292
+ [LINK](entry, linkpath, link$1, done) {
31293
+ const ls = `${link$1}Sync`;
31294
+ try {
31295
+ fs[ls](linkpath, String(entry.absolute));
31296
+ done();
31297
+ entry.resume();
31298
+ } catch (er) {
31299
+ return this[ONERROR](er, entry);
31300
+ }
31301
+ }
31302
+ };
31339
31303
 
31340
31304
  //#endregion
31341
- //#region src/cli/utils/banner.ts
31342
- const BANNER_LINES = [
31343
- "██████╗ █████╗ ███████╗███████╗ ██╗ ██╗██╗ ██╗",
31344
- "██╔══██╗██╔══██╗██╔════╝██╔════╝ ██║ ██║██║ ██║",
31345
- "██████╔╝███████║███████╗█████╗ ███████║███████║",
31346
- "██╔══██╗██╔══██║╚════██║██╔══╝ ╚════██║╚════██║",
31347
- "██████╔╝██║ ██║███████║███████╗ ██║ ██║",
31348
- "╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝ ╚═╝"
31349
- ];
31350
- /**
31351
- * Print the Base44 banner with smooth animation if supported,
31352
- * or fall back to static banner.
31353
- */
31354
- async function printBanner() {
31355
- if (process.stdout.isTTY) await printAnimatedLines(BANNER_LINES);
31356
- else console.log(theme.colors.base44Orange(BANNER_LINES.join("\n")));
31357
- }
31305
+ //#region node_modules/tar/dist/esm/extract.js
31306
+ const extractFileSync = (opt) => {
31307
+ const u$2 = new UnpackSync(opt);
31308
+ const file = opt.file;
31309
+ const stat = fs.statSync(file);
31310
+ const readSize = opt.maxReadSize || 16 * 1024 * 1024;
31311
+ new ReadStreamSync(file, {
31312
+ readSize,
31313
+ size: stat.size
31314
+ }).pipe(u$2);
31315
+ };
31316
+ const extractFile = (opt, _$2) => {
31317
+ const u$2 = new Unpack(opt);
31318
+ const readSize = opt.maxReadSize || 16 * 1024 * 1024;
31319
+ const file = opt.file;
31320
+ return new Promise((resolve$1, reject) => {
31321
+ u$2.on("error", reject);
31322
+ u$2.on("close", resolve$1);
31323
+ fs.stat(file, (er, stat) => {
31324
+ if (er) reject(er);
31325
+ else {
31326
+ const stream = new ReadStream(file, {
31327
+ readSize,
31328
+ size: stat.size
31329
+ });
31330
+ stream.on("error", reject);
31331
+ stream.pipe(u$2);
31332
+ }
31333
+ });
31334
+ });
31335
+ };
31336
+ const extract = makeCommand(extractFileSync, extractFile, (opt) => new UnpackSync(opt), (opt) => new Unpack(opt), (opt, files) => {
31337
+ if (files?.length) filesFilter(opt, files);
31338
+ });
31358
31339
 
31359
31340
  //#endregion
31360
- //#region src/cli/utils/runCommand.ts
31361
- /**
31362
- * Wraps a command function with the Base44 intro/outro and error handling.
31363
- * All CLI commands should use this utility to ensure consistent branding.
31364
- *
31365
- * **Responsibilities**:
31366
- * - Displays the intro (simple tag or full ASCII banner)
31367
- * - Loads `.env.local` from the project root if available
31368
- * - Checks authentication if `requireAuth` is set
31369
- * - Runs the command function
31370
- * - Displays the outro message returned by the command
31371
- * - Handles errors and exits with code 1 on failure
31372
- *
31373
- * **Important**: Commands should NOT call `intro()` or `outro()` directly.
31374
- * This function handles both. Commands can return an optional `outroMessage`
31375
- * which will be displayed at the end.
31376
- *
31377
- * @param commandFn - The async function to execute. Returns `RunCommandResult` with optional `outroMessage`.
31378
- * @param options - Optional configuration for the command wrapper
31379
- *
31380
- * @example
31381
- * // Standard command with outro message
31382
- * async function myAction(): Promise<RunCommandResult> {
31383
- * // ... do work ...
31384
- * return { outroMessage: "Done!" };
31385
- * }
31386
- *
31387
- * export const myCommand = new Command("my-command")
31388
- * .action(async () => {
31389
- * await runCommand(myAction);
31390
- * });
31391
- *
31392
- * @example
31393
- * // Command requiring authentication with full banner
31394
- * export const myCommand = new Command("my-command")
31395
- * .action(async () => {
31396
- * await runCommand(myAction, { requireAuth: true, fullBanner: true });
31397
- * });
31398
- */
31399
- async function runCommand(commandFn, options) {
31400
- console.log();
31401
- if (options?.fullBanner) {
31402
- await printBanner();
31403
- Ie("");
31404
- } else Ie(theme.colors.base44OrangeBackground(" Base 44 "));
31405
- await loadProjectEnv();
31341
+ //#region node_modules/tar/dist/esm/replace.js
31342
+ const replaceSync = (opt, files) => {
31343
+ const p$1 = new PackSync(opt);
31344
+ let threw = true;
31345
+ let fd;
31346
+ let position;
31406
31347
  try {
31407
- if (options?.requireAuth) {
31408
- if (!await isLoggedIn()) {
31409
- M.info("You need to login first to continue.");
31410
- await login();
31348
+ try {
31349
+ fd = fs.openSync(opt.file, "r+");
31350
+ } catch (er) {
31351
+ if (er?.code === "ENOENT") fd = fs.openSync(opt.file, "w+");
31352
+ else throw er;
31353
+ }
31354
+ const st = fs.fstatSync(fd);
31355
+ const headBuf = Buffer.alloc(512);
31356
+ POSITION: for (position = 0; position < st.size; position += 512) {
31357
+ for (let bufPos = 0, bytes = 0; bufPos < 512; bufPos += bytes) {
31358
+ bytes = fs.readSync(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos);
31359
+ if (position === 0 && headBuf[0] === 31 && headBuf[1] === 139) throw new Error("cannot append to compressed archives");
31360
+ if (!bytes) break POSITION;
31411
31361
  }
31362
+ const h$2 = new Header(headBuf);
31363
+ if (!h$2.cksumValid) break;
31364
+ const entryBlockSize = 512 * Math.ceil((h$2.size || 0) / 512);
31365
+ if (position + entryBlockSize + 512 > st.size) break;
31366
+ position += entryBlockSize;
31367
+ if (opt.mtimeCache && h$2.mtime) opt.mtimeCache.set(String(h$2.path), h$2.mtime);
31412
31368
  }
31413
- const { outroMessage } = await commandFn();
31414
- Se(outroMessage || "");
31415
- } catch (e$1) {
31416
- if (e$1 instanceof Error) M.error(e$1.stack ?? e$1.message);
31417
- else M.error(String(e$1));
31418
- process.exit(1);
31419
- }
31420
- }
31421
-
31422
- //#endregion
31423
- //#region src/cli/utils/runTask.ts
31424
- /**
31425
- * Wraps an async operation with automatic spinner management.
31426
- * The spinner is automatically started, and stopped on both success and error.
31427
- *
31428
- * @param startMessage - Message to show when spinner starts
31429
- * @param operation - The async operation to execute. Receives an updateMessage function
31430
- * to update the spinner text during long-running operations.
31431
- * @param options - Optional configuration for success/error messages
31432
- * @returns The result of the operation
31433
- *
31434
- * @example
31435
- * // Simple usage
31436
- * const data = await runTask(
31437
- * "Fetching data...",
31438
- * async () => {
31439
- * const response = await fetch(url);
31440
- * return response.json();
31441
- * },
31442
- * {
31443
- * successMessage: "Data fetched successfully",
31444
- * errorMessage: "Failed to fetch data",
31445
- * }
31446
- * );
31447
- *
31448
- * @example
31449
- * // With progress updates
31450
- * const result = await runTask(
31451
- * "Processing files...",
31452
- * async (updateMessage) => {
31453
- * for (const file of files) {
31454
- * updateMessage(`Processing ${file.name}...`);
31455
- * await process(file);
31456
- * }
31457
- * return files.length;
31458
- * },
31459
- * { successMessage: "All files processed" }
31460
- * );
31461
- */
31462
- async function runTask(startMessage, operation, options) {
31463
- const s = Y();
31464
- s.start(startMessage);
31465
- const updateMessage = (message) => s.message(message);
31466
- try {
31467
- const result = await operation(updateMessage);
31468
- s.stop(options?.successMessage || startMessage);
31469
- return result;
31470
- } catch (error) {
31471
- s.stop(options?.errorMessage || "Failed");
31472
- throw error;
31369
+ threw = false;
31370
+ streamSync(opt, p$1, position, fd, files);
31371
+ } finally {
31372
+ if (threw) try {
31373
+ fs.closeSync(fd);
31374
+ } catch (er) {}
31473
31375
  }
31474
- }
31475
-
31476
- //#endregion
31477
- //#region src/cli/utils/prompts.ts
31478
- /**
31479
- * Standard onCancel handler for prompt groups.
31480
- * Exits the process gracefully when the user cancels.
31481
- */
31482
- const onPromptCancel = () => {
31483
- xe("Operation cancelled.");
31484
- process.exit(0);
31485
31376
  };
31486
-
31487
- //#endregion
31488
- //#region src/cli/utils/urls.ts
31489
- /**
31490
- * Gets the dashboard URL for a project.
31491
- *
31492
- * @param projectId - Optional project ID. If not provided, uses BASE44_CLIENT_ID from env.
31493
- * @returns The dashboard URL
31494
- * @throws Error if no projectId provided and BASE44_CLIENT_ID is not configured
31495
- */
31496
- function getDashboardUrl(projectId) {
31497
- const id = projectId ?? getBase44ClientId();
31498
- if (!id) throw new Error("App not configured. BASE44_CLIENT_ID environment variable is required. Set it in your .env.local file.");
31499
- return `${getBase44ApiUrl()}/apps/${id}/editor/workspace/overview`;
31500
- }
31501
-
31502
- //#endregion
31503
- //#region src/cli/commands/auth/login.ts
31504
- async function generateAndDisplayDeviceCode() {
31505
- const deviceCodeResponse = await runTask("Generating device code...", async () => {
31506
- return await generateDeviceCode();
31507
- }, {
31508
- successMessage: "Device code generated",
31509
- errorMessage: "Failed to generate device code"
31377
+ const streamSync = (opt, p$1, position, fd, files) => {
31378
+ const stream = new WriteStreamSync(opt.file, {
31379
+ fd,
31380
+ start: position
31510
31381
  });
31511
- M.info(`Verification code: ${theme.styles.bold(deviceCodeResponse.userCode)}\nPlease confirm this code at: ${deviceCodeResponse.verificationUri}`);
31512
- return deviceCodeResponse;
31513
- }
31514
- async function waitForAuthentication(deviceCode, expiresIn, interval) {
31515
- let tokenResponse;
31516
- try {
31517
- await runTask("Waiting for authentication...", async () => {
31518
- await pWaitFor(async () => {
31519
- const result = await getTokenFromDeviceCode(deviceCode);
31520
- if (result !== null) {
31521
- tokenResponse = result;
31522
- return true;
31523
- }
31524
- return false;
31525
- }, {
31526
- interval: interval * 1e3,
31527
- timeout: expiresIn * 1e3
31382
+ p$1.pipe(stream);
31383
+ addFilesSync(p$1, files);
31384
+ };
31385
+ const replaceAsync = (opt, files) => {
31386
+ files = Array.from(files);
31387
+ const p$1 = new Pack(opt);
31388
+ const getPos = (fd, size, cb_) => {
31389
+ const cb = (er, pos$1) => {
31390
+ if (er) fs.close(fd, (_$2) => cb_(er));
31391
+ else cb_(null, pos$1);
31392
+ };
31393
+ let position = 0;
31394
+ if (size === 0) return cb(null, 0);
31395
+ let bufPos = 0;
31396
+ const headBuf = Buffer.alloc(512);
31397
+ const onread = (er, bytes) => {
31398
+ if (er || typeof bytes === "undefined") return cb(er);
31399
+ bufPos += bytes;
31400
+ if (bufPos < 512 && bytes) return fs.read(fd, headBuf, bufPos, headBuf.length - bufPos, position + bufPos, onread);
31401
+ if (position === 0 && headBuf[0] === 31 && headBuf[1] === 139) return cb(/* @__PURE__ */ new Error("cannot append to compressed archives"));
31402
+ if (bufPos < 512) return cb(null, position);
31403
+ const h$2 = new Header(headBuf);
31404
+ if (!h$2.cksumValid) return cb(null, position);
31405
+ /* c8 ignore next */
31406
+ const entryBlockSize = 512 * Math.ceil((h$2.size ?? 0) / 512);
31407
+ if (position + entryBlockSize + 512 > size) return cb(null, position);
31408
+ position += entryBlockSize + 512;
31409
+ if (position >= size) return cb(null, position);
31410
+ if (opt.mtimeCache && h$2.mtime) opt.mtimeCache.set(String(h$2.path), h$2.mtime);
31411
+ bufPos = 0;
31412
+ fs.read(fd, headBuf, 0, 512, position, onread);
31413
+ };
31414
+ fs.read(fd, headBuf, 0, 512, position, onread);
31415
+ };
31416
+ return new Promise((resolve$1, reject) => {
31417
+ p$1.on("error", reject);
31418
+ let flag = "r+";
31419
+ const onopen = (er, fd) => {
31420
+ if (er && er.code === "ENOENT" && flag === "r+") {
31421
+ flag = "w+";
31422
+ return fs.open(opt.file, flag, onopen);
31423
+ }
31424
+ if (er || !fd) return reject(er);
31425
+ fs.fstat(fd, (er$1, st) => {
31426
+ if (er$1) return fs.close(fd, () => reject(er$1));
31427
+ getPos(fd, st.size, (er$2, position) => {
31428
+ if (er$2) return reject(er$2);
31429
+ const stream = new WriteStream(opt.file, {
31430
+ fd,
31431
+ start: position
31432
+ });
31433
+ p$1.pipe(stream);
31434
+ stream.on("error", reject);
31435
+ stream.on("close", resolve$1);
31436
+ addFilesAsync(p$1, files);
31437
+ });
31528
31438
  });
31529
- }, {
31530
- successMessage: "Authentication completed!",
31531
- errorMessage: "Authentication failed"
31439
+ };
31440
+ fs.open(opt.file, flag, onopen);
31441
+ });
31442
+ };
31443
+ const addFilesSync = (p$1, files) => {
31444
+ files.forEach((file) => {
31445
+ if (file.charAt(0) === "@") list({
31446
+ file: path.resolve(p$1.cwd, file.slice(1)),
31447
+ sync: true,
31448
+ noResume: true,
31449
+ onReadEntry: (entry) => p$1.add(entry)
31532
31450
  });
31533
- } catch (error) {
31534
- if (error instanceof Error && error.message.includes("timed out")) throw new Error("Authentication timed out. Please try again.");
31535
- throw error;
31536
- }
31537
- if (tokenResponse === void 0) throw new Error("Failed to retrieve authentication token.");
31538
- return tokenResponse;
31539
- }
31540
- async function saveAuthData(response, userInfo) {
31541
- const expiresAt = Date.now() + response.expiresIn * 1e3;
31542
- await writeAuth({
31543
- accessToken: response.accessToken,
31544
- refreshToken: response.refreshToken,
31545
- expiresAt,
31546
- email: userInfo.email,
31547
- name: userInfo.name
31451
+ else p$1.add(file);
31548
31452
  });
31549
- }
31550
- async function login() {
31551
- const deviceCodeResponse = await generateAndDisplayDeviceCode();
31552
- const token = await waitForAuthentication(deviceCodeResponse.deviceCode, deviceCodeResponse.expiresIn, deviceCodeResponse.interval);
31553
- const userInfo = await getUserInfo(token.accessToken);
31554
- await saveAuthData(token, userInfo);
31555
- return { outroMessage: `Successfully logged in as ${theme.styles.bold(userInfo.email)}` };
31556
- }
31557
- const loginCommand = new Command("login").description("Authenticate with Base44").action(async () => {
31558
- await runCommand(login);
31559
- });
31453
+ p$1.end();
31454
+ };
31455
+ const addFilesAsync = async (p$1, files) => {
31456
+ for (let i$1 = 0; i$1 < files.length; i$1++) {
31457
+ const file = String(files[i$1]);
31458
+ if (file.charAt(0) === "@") await list({
31459
+ file: path.resolve(String(p$1.cwd), file.slice(1)),
31460
+ noResume: true,
31461
+ onReadEntry: (entry) => p$1.add(entry)
31462
+ });
31463
+ else p$1.add(file);
31464
+ }
31465
+ p$1.end();
31466
+ };
31467
+ const replace = makeCommand(
31468
+ replaceSync,
31469
+ replaceAsync,
31470
+ /* c8 ignore start */
31471
+ () => {
31472
+ throw new TypeError("file is required");
31473
+ },
31474
+ () => {
31475
+ throw new TypeError("file is required");
31476
+ },
31477
+ /* c8 ignore stop */
31478
+ (opt, entries) => {
31479
+ if (!isFile(opt)) throw new TypeError("file is required");
31480
+ if (opt.gzip || opt.brotli || opt.zstd || opt.file.endsWith(".br") || opt.file.endsWith(".tbr")) throw new TypeError("cannot append to compressed archives");
31481
+ if (!entries?.length) throw new TypeError("no paths specified to add/replace");
31482
+ }
31483
+ );
31560
31484
 
31561
31485
  //#endregion
31562
- //#region src/cli/commands/auth/whoami.ts
31563
- async function whoami() {
31564
- const auth = await readAuth();
31565
- return { outroMessage: `Logged in as: ${theme.styles.bold(auth.email)}` };
31566
- }
31567
- const whoamiCommand = new Command("whoami").description("Display current authenticated user").action(async () => {
31568
- await runCommand(whoami, { requireAuth: true });
31486
+ //#region node_modules/tar/dist/esm/update.js
31487
+ const update = makeCommand(replace.syncFile, replace.asyncFile, replace.syncNoFile, replace.asyncNoFile, (opt, entries = []) => {
31488
+ replace.validate?.(opt, entries);
31489
+ mtimeFilter(opt);
31569
31490
  });
31491
+ const mtimeFilter = (opt) => {
31492
+ const filter = opt.filter;
31493
+ if (!opt.mtimeCache) opt.mtimeCache = /* @__PURE__ */ new Map();
31494
+ opt.filter = filter ? (path$17, stat) => filter(path$17, stat) && !((opt.mtimeCache?.get(path$17) ?? stat.mtime ?? 0) > (stat.mtime ?? 0)) : (path$17, stat) => !((opt.mtimeCache?.get(path$17) ?? stat.mtime ?? 0) > (stat.mtime ?? 0));
31495
+ };
31570
31496
 
31571
31497
  //#endregion
31572
- //#region src/cli/commands/auth/logout.ts
31573
- async function logout() {
31574
- await deleteAuth();
31575
- return { outroMessage: "Logged out successfully" };
31498
+ //#region src/core/site/deploy.ts
31499
+ async function deploySite(siteOutputDir) {
31500
+ if (!await pathExists(siteOutputDir)) throw new Error(`Output directory does not exist: ${siteOutputDir}. Make sure to build your project first.`);
31501
+ if ((await getSiteFilePaths(siteOutputDir)).length === 0) throw new Error(`No files found in output directory: ${siteOutputDir}. Make sure to build your project first.`);
31502
+ const archivePath = join(tmpdir(), `base44-site-${getBase44ClientId()}-${randomUUID().toString()}.tar.gz`);
31503
+ try {
31504
+ await createArchive(siteOutputDir, archivePath);
31505
+ return await uploadSite(archivePath);
31506
+ } finally {
31507
+ await deleteFile(archivePath);
31508
+ }
31509
+ }
31510
+ async function createArchive(pathToArchive, targetArchivePath) {
31511
+ await create({
31512
+ gzip: true,
31513
+ file: targetArchivePath,
31514
+ cwd: pathToArchive
31515
+ }, ["."]);
31576
31516
  }
31577
- const logoutCommand = new Command("logout").description("Logout from current device").action(async () => {
31578
- await runCommand(logout);
31579
- });
31580
31517
 
31581
31518
  //#endregion
31582
31519
  //#region src/cli/commands/entities/push.ts
@@ -38420,8 +38357,9 @@ async function executeCreate({ template, name: rawName, description, projectPath
38420
38357
  finalAppUrl = appUrl;
38421
38358
  }
38422
38359
  }
38360
+ const dashboardUrl = `${getBase44ApiUrl()}/apps/${projectId}/editor/preview`;
38423
38361
  M.message(`${theme.styles.header("Project")}: ${theme.colors.base44Orange(name$1)}`);
38424
- M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(projectId))}`);
38362
+ M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(dashboardUrl)}`);
38425
38363
  if (finalAppUrl) M.message(`${theme.styles.header("Site")}: ${theme.colors.links(finalAppUrl)}`);
38426
38364
  return { outroMessage: "Your project is set up and ready to use" };
38427
38365
  }
@@ -38971,7 +38909,10 @@ var open_default = open;
38971
38909
  //#endregion
38972
38910
  //#region src/cli/commands/project/dashboard.ts
38973
38911
  async function openDashboard() {
38974
- const dashboardUrl = getDashboardUrl();
38912
+ await loadProjectEnv();
38913
+ const projectId = getBase44ClientId();
38914
+ if (!projectId) throw new Error("App not configured. BASE44_CLIENT_ID environment variable is required. Set it in your .env.local file.");
38915
+ const dashboardUrl = `${getBase44ApiUrl()}/apps/${projectId}/editor/workspace/overview`;
38975
38916
  await open_default(dashboardUrl);
38976
38917
  return { outroMessage: `Dashboard opened at ${dashboardUrl}` };
38977
38918
  }
@@ -38979,35 +38920,6 @@ const dashboardCommand = new Command("dashboard").description("Open the app dash
38979
38920
  await runCommand(openDashboard, { requireAuth: true });
38980
38921
  });
38981
38922
 
38982
- //#endregion
38983
- //#region src/cli/commands/project/deploy.ts
38984
- async function deployAction$1(options) {
38985
- const projectData = await readProjectConfig();
38986
- if (!hasResourcesToDeploy(projectData)) return { outroMessage: "No resources found to deploy" };
38987
- const { project, entities, functions } = projectData;
38988
- const summaryLines = [];
38989
- if (entities.length > 0) summaryLines.push(` - ${entities.length} ${entities.length === 1 ? "entity" : "entities"}`);
38990
- if (functions.length > 0) summaryLines.push(` - ${functions.length} ${functions.length === 1 ? "function" : "functions"}`);
38991
- if (project.site?.outputDirectory) summaryLines.push(` - Site from ${project.site.outputDirectory}`);
38992
- if (!options.yes) {
38993
- M.warn(`This will update your Base44 app with:\n${summaryLines.join("\n")}`);
38994
- const shouldDeploy = await ye({ message: "Are you sure you want to continue?" });
38995
- if (pD(shouldDeploy) || !shouldDeploy) return { outroMessage: "Deployment cancelled" };
38996
- } else M.info(`Deploying:\n${summaryLines.join("\n")}`);
38997
- const result = await runTask("Deploying your app...", async () => {
38998
- return await deployAll(projectData);
38999
- }, {
39000
- successMessage: theme.colors.base44Orange("Deployment completed"),
39001
- errorMessage: "Deployment failed"
39002
- });
39003
- M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl())}`);
39004
- if (result.appUrl) M.message(`${theme.styles.header("App URL")}: ${theme.colors.links(result.appUrl)}`);
39005
- return { outroMessage: "App deployed successfully" };
39006
- }
39007
- const deployCommand = new Command("deploy").description("Deploy all project resources (entities, functions, and site)").option("-y, --yes", "Skip confirmation prompt").action(async (options) => {
39008
- await runCommand(() => deployAction$1(options), { requireAuth: true });
39009
- });
39010
-
39011
38923
  //#endregion
39012
38924
  //#region src/cli/commands/project/link.ts
39013
38925
  function validateNonInteractiveFlags(command) {
@@ -39059,7 +38971,8 @@ async function link(options) {
39059
38971
  errorMessage: "Failed to create project"
39060
38972
  });
39061
38973
  await writeEnvLocal(projectRoot.root, projectId);
39062
- M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(projectId))}`);
38974
+ const dashboardUrl = `${getBase44ApiUrl()}/apps/${projectId}/editor/workspace/overview`;
38975
+ M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(dashboardUrl)}`);
39063
38976
  return { outroMessage: "Project linked" };
39064
38977
  }
39065
38978
  const linkCommand = new Command("link").description("Link a local project to a Base44 project").option("-c, --create", "Create a new project (skip selection prompt)").option("-n, --name <name>", "Project name (required when --create is used)").option("-d, --description <description>", "Project description").hook("preAction", validateNonInteractiveFlags).action(async (options) => {
@@ -39101,7 +39014,6 @@ program.addCommand(whoamiCommand);
39101
39014
  program.addCommand(logoutCommand);
39102
39015
  program.addCommand(createCommand);
39103
39016
  program.addCommand(dashboardCommand);
39104
- program.addCommand(deployCommand);
39105
39017
  program.addCommand(linkCommand);
39106
39018
  program.addCommand(entitiesPushCommand);
39107
39019
  program.addCommand(functionsDeployCommand);