@archlast/cli 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,7 @@ CLI tool for Archlast development, deployment, and Docker lifecycle management.
6
6
 
7
7
  - Node.js 18+
8
8
  - Docker Desktop or Docker Engine
9
+ - Bun 1.3+
9
10
 
10
11
  ## Installation
11
12
 
@@ -13,6 +14,16 @@ CLI tool for Archlast development, deployment, and Docker lifecycle management.
13
14
  npm install -g @archlast/cli
14
15
  ```
15
16
 
17
+ On Windows, ensure Bun is on your PATH (the installer adds it, but terminals need a restart):
18
+
19
+ ```powershell
20
+ [Environment]::SetEnvironmentVariable(
21
+ "Path",
22
+ "$env:Path;$env:USERPROFILE\\.bun\\bin",
23
+ "User"
24
+ )
25
+ ```
26
+
16
27
  ## Quick start
17
28
 
18
29
  ```bash
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAcjF;AAED,qBAAa,uBAAwB,SAAQ,KAAK;;CAUjD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY9E;AAED,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CA2C5D;AAED,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK5E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOjD"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAMA,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAcjF;AAED,qBAAa,uBAAwB,SAAQ,KAAK;;CAUjD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY9E;AAED,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAuD5D;AAED,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK5E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAOjD"}
package/dist/cli.js CHANGED
@@ -263846,7 +263846,7 @@ ${suffix}`;
263846
263846
  var require_SFTP = __commonJS((exports, module) => {
263847
263847
  var EventEmitter4 = __require("events");
263848
263848
  var fs7 = __require("fs");
263849
- var { constants } = fs7;
263849
+ var { constants: constants2 } = fs7;
263850
263850
  var {
263851
263851
  Readable: ReadableStream,
263852
263852
  Writable: WritableStream
@@ -265606,25 +265606,25 @@ var require_SFTP = __commonJS((exports, module) => {
265606
265606
  this.extended = initial && initial.extended;
265607
265607
  }
265608
265608
  isDirectory() {
265609
- return (this.mode & constants.S_IFMT) === constants.S_IFDIR;
265609
+ return (this.mode & constants2.S_IFMT) === constants2.S_IFDIR;
265610
265610
  }
265611
265611
  isFile() {
265612
- return (this.mode & constants.S_IFMT) === constants.S_IFREG;
265612
+ return (this.mode & constants2.S_IFMT) === constants2.S_IFREG;
265613
265613
  }
265614
265614
  isBlockDevice() {
265615
- return (this.mode & constants.S_IFMT) === constants.S_IFBLK;
265615
+ return (this.mode & constants2.S_IFMT) === constants2.S_IFBLK;
265616
265616
  }
265617
265617
  isCharacterDevice() {
265618
- return (this.mode & constants.S_IFMT) === constants.S_IFCHR;
265618
+ return (this.mode & constants2.S_IFMT) === constants2.S_IFCHR;
265619
265619
  }
265620
265620
  isSymbolicLink() {
265621
- return (this.mode & constants.S_IFMT) === constants.S_IFLNK;
265621
+ return (this.mode & constants2.S_IFMT) === constants2.S_IFLNK;
265622
265622
  }
265623
265623
  isFIFO() {
265624
- return (this.mode & constants.S_IFMT) === constants.S_IFIFO;
265624
+ return (this.mode & constants2.S_IFMT) === constants2.S_IFIFO;
265625
265625
  }
265626
265626
  isSocket() {
265627
- return (this.mode & constants.S_IFMT) === constants.S_IFSOCK;
265627
+ return (this.mode & constants2.S_IFMT) === constants2.S_IFSOCK;
265628
265628
  }
265629
265629
  }
265630
265630
  function attrsToBytes(attrs) {
@@ -272716,7 +272716,7 @@ var require_end_of_stream2 = __commonJS((exports, module) => {
272716
272716
 
272717
272717
  // ../../node_modules/.bun/tar-stream@2.2.0/node_modules/tar-stream/pack.js
272718
272718
  var require_pack = __commonJS((exports, module) => {
272719
- var constants = require_fs_constants();
272719
+ var constants2 = require_fs_constants();
272720
272720
  var eos = require_end_of_stream2();
272721
272721
  var inherits = require_inherits();
272722
272722
  var alloc = Buffer.alloc;
@@ -272734,16 +272734,16 @@ var require_pack = __commonJS((exports, module) => {
272734
272734
  self2.push(END_OF_TAR.slice(0, 512 - size));
272735
272735
  };
272736
272736
  function modeToType(mode) {
272737
- switch (mode & constants.S_IFMT) {
272738
- case constants.S_IFBLK:
272737
+ switch (mode & constants2.S_IFMT) {
272738
+ case constants2.S_IFBLK:
272739
272739
  return "block-device";
272740
- case constants.S_IFCHR:
272740
+ case constants2.S_IFCHR:
272741
272741
  return "character-device";
272742
- case constants.S_IFDIR:
272742
+ case constants2.S_IFDIR:
272743
272743
  return "directory";
272744
- case constants.S_IFIFO:
272744
+ case constants2.S_IFIFO:
272745
272745
  return "fifo";
272746
- case constants.S_IFLNK:
272746
+ case constants2.S_IFLNK:
272747
272747
  return "symlink";
272748
272748
  }
272749
272749
  return "file";
@@ -314824,6 +314824,22 @@ async function generateDI(outputDir, injectables) {
314824
314824
  }
314825
314825
 
314826
314826
  // src/generator.ts
314827
+ async function readTextIfExists(filePath) {
314828
+ const bun = globalThis.Bun;
314829
+ if (bun?.file) {
314830
+ const file = bun.file(filePath);
314831
+ if (await file.exists()) {
314832
+ return await file.text();
314833
+ }
314834
+ return null;
314835
+ }
314836
+ try {
314837
+ await fs4.promises.access(filePath, fs4.constants.F_OK);
314838
+ return await fs4.promises.readFile(filePath, "utf-8");
314839
+ } catch {
314840
+ return null;
314841
+ }
314842
+ }
314827
314843
  function resolveImport(typeText, sourceFile) {
314828
314844
  return typeText.replace(/import\("([^"]+)"\)\./g, (match2, path6) => {
314829
314845
  if (path6.includes("packages/server/src/db/sqlite")) {
@@ -315328,20 +315344,24 @@ class TypeGenerator {
315328
315344
  const schemaIndexPath = join5(schemaFolderPath, "index.ts");
315329
315345
  let schemaContent = "";
315330
315346
  let schemaSource = "";
315331
- if (await Bun.file(schemaPath).exists()) {
315332
- schemaContent = await Bun.file(schemaPath).text();
315347
+ const schemaFile = await readTextIfExists(schemaPath);
315348
+ if (schemaFile !== null) {
315349
+ schemaContent = schemaFile;
315333
315350
  schemaSource = "schema.ts";
315334
315351
  console.log(`Reading schema from ${schemaPath}`);
315335
- } else if (await Bun.file(schemaIndexPath).exists()) {
315336
- schemaContent = await Bun.file(schemaIndexPath).text();
315337
- schemaSource = "schema/index.ts";
315338
- console.log(`Reading schema from ${schemaIndexPath}`);
315339
315352
  } else {
315340
- const folderFiles = await this.scanSchemaFolder(schemaFolderPath);
315341
- schemaContent = folderFiles.map((f) => f.content).join(`
315353
+ const schemaIndexFile = await readTextIfExists(schemaIndexPath);
315354
+ if (schemaIndexFile !== null) {
315355
+ schemaContent = schemaIndexFile;
315356
+ schemaSource = "schema/index.ts";
315357
+ console.log(`Reading schema from ${schemaIndexPath}`);
315358
+ } else {
315359
+ const folderFiles = await this.scanSchemaFolder(schemaFolderPath);
315360
+ schemaContent = folderFiles.map((f) => f.content).join(`
315342
315361
  `);
315343
- schemaSource = "schema/*.ts";
315344
- console.log(`Reading schema from folder: ${schemaFolderPath}`);
315362
+ schemaSource = "schema/*.ts";
315363
+ console.log(`Reading schema from folder: ${schemaFolderPath}`);
315364
+ }
315345
315365
  }
315346
315366
  const tableMatches = schemaContent.matchAll(/(?:export\s+(?:const|let)\s+)?(\w+)\s*(?::\s*\w+)?\s*[:=]\s*defineTable\s*\(\s*\{([\s\S]+?)\n\s*}(?:,\s*({[\s\S]+?\n\s*}))?\s*\)/g);
315347
315367
  const tables = {};
@@ -316599,14 +316619,14 @@ function extractFromEnv(content, varName) {
316599
316619
  return null;
316600
316620
  }
316601
316621
  function readAdminToken(archlastPath) {
316602
- const apiKey = process.env.ARCHLAST_API_KEY;
316603
- const validation = validateApiKey(apiKey || "");
316604
- if (!validation.valid) {
316622
+ const envApiKey = process.env.ARCHLAST_API_KEY;
316623
+ if (envApiKey) {
316624
+ const validation = validateApiKey(envApiKey);
316625
+ if (validation.valid) {
316626
+ return envApiKey;
316627
+ }
316605
316628
  throw new Error(validation.error || "Invalid API key");
316606
316629
  }
316607
- if (apiKey) {
316608
- return apiKey;
316609
- }
316610
316630
  const searchPaths = [];
316611
316631
  if (archlastPath) {
316612
316632
  searchPaths.push(path6.resolve(archlastPath, ".env.local"));
@@ -316616,11 +316636,16 @@ function readAdminToken(archlastPath) {
316616
316636
  searchPaths.push(path6.resolve(process.cwd(), ".env"));
316617
316637
  let currentDir = process.cwd();
316618
316638
  for (let i = 0;i < 5; i++) {
316619
- const repoArchlast = path6.join(currentDir, "apps", "archlast", ".env.local");
316639
+ const repoArchlastLocal = path6.join(currentDir, "apps", "archlast", ".env.local");
316640
+ const repoArchlast = path6.join(currentDir, "apps", "archlast", ".env");
316641
+ if (fs5.existsSync(repoArchlastLocal)) {
316642
+ searchPaths.push(repoArchlastLocal);
316643
+ }
316620
316644
  if (fs5.existsSync(repoArchlast)) {
316621
316645
  searchPaths.push(repoArchlast);
316622
- break;
316623
316646
  }
316647
+ if (searchPaths.length > 2)
316648
+ break;
316624
316649
  const parent = path6.dirname(currentDir);
316625
316650
  if (parent === currentDir)
316626
316651
  break;
@@ -316632,7 +316657,11 @@ function readAdminToken(archlastPath) {
316632
316657
  const content = fs5.readFileSync(filePath, "utf-8");
316633
316658
  const key = extractFromEnv(content, "ARCHLAST_API_KEY");
316634
316659
  if (key) {
316635
- return key;
316660
+ const validation = validateApiKey(key);
316661
+ if (validation.valid) {
316662
+ return key;
316663
+ }
316664
+ console.warn(`Warning: Invalid API key format in ${filePath}: ${validation.error}`);
316636
316665
  }
316637
316666
  }
316638
316667
  }
@@ -316717,9 +316746,9 @@ class CodeUploader {
316717
316746
  if (!response.ok) {
316718
316747
  if (response.status === 401) {
316719
316748
  const error = await response.text();
316720
- throw new Error(`Authentication failed: ${error || "Invalid admin token"}
316749
+ throw new Error(`Authentication failed: ${error || "Invalid API key"}
316721
316750
 
316722
- Please create a token in the dashboard (Settings → API Tokens) and update ARCHLAST_ADMIN_TOKEN in your .env file.`);
316751
+ Please create an API key in the admin dashboard (http://localhost:4001/dashboard/settings) and set ARCHLAST_API_KEY in your .env file.`);
316723
316752
  }
316724
316753
  const localFiles2 = await this.collectAllFiles();
316725
316754
  return {
@@ -316817,9 +316846,9 @@ Please create a token in the dashboard (Settings → API Tokens) and update ARCH
316817
316846
  if (response.status === 401) {
316818
316847
  return {
316819
316848
  success: false,
316820
- message: `Authentication failed: ${errorText || "Invalid admin token"}
316849
+ message: `Authentication failed: ${errorText || "Invalid API key"}
316821
316850
 
316822
- Please create a token in the dashboard (Settings → API Tokens) and update ARCHLAST_ADMIN_TOKEN in your .env file.`
316851
+ Please create an API key in the admin dashboard (http://localhost:4001/dashboard/settings) and set ARCHLAST_API_KEY in your .env file.`
316823
316852
  };
316824
316853
  }
316825
316854
  return { success: false, message: errorText };
@@ -322320,7 +322349,7 @@ async function configCommand(options) {
322320
322349
 
322321
322350
  // src/cli.ts
322322
322351
  var program2 = new Command;
322323
- program2.name("archlast").description("Archlast CLI for development and deployment").version("0.1.4");
322352
+ program2.name("archlast").description("Archlast CLI for development and deployment").version("0.1.6");
322324
322353
  program2.command("build").description("Generate types without deploying").option("--path <path>", "Path to archlast folder", ".").action(buildCommand);
322325
322354
  program2.command("dev").description("Start development mode with file watching").option("-p, --port <port>", "Server port", "3001").option("--path <path>", "Path to archlast folder", ".").option("--server <url>", "Server URL for code upload", "http://localhost:4000").option("--max-poll <number>", "Maximum server polling retries", "30").action(devCommand);
322326
322355
  program2.command("deploy").description("Deploy to production").option("--path <path>", "Path to archlast folder", ".").option("--server <url>", "Server URL for code upload", "http://localhost:4000").option("--max-poll <number>", "Maximum server polling retries", "30").action(deployCommand);
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAmC5C,qBAAa,aAAa;IACtB,OAAO,CAAC,YAAY,CAAS;gBAEjB,YAAY,EAAE,MAAM;IAI1B,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;YAiDzC,uBAAuB;YAgDvB,0BAA0B;IA6CxC,OAAO,CAAC,kBAAkB;IA6H1B,OAAO,CAAC,eAAe;IA+GvB,OAAO,CAAC,cAAc;IAiDtB,OAAO,CAAC,eAAe;YA6RT,2BAA2B;IAwPzC;;OAEG;YACW,gBAAgB;YAyBhB,gBAAgB;YAuDhB,gBAAgB;IAgF9B;;;OAGG;YACW,kBAAkB;YA2GlB,mBAAmB;IA0iBjC,OAAO,CAAC,mBAAmB;IAS3B;;;OAGG;IACG,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC/D;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAuBzB;;OAEG;IACH,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IA2HtD;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAkB5B"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAqD5C,qBAAa,aAAa;IACtB,OAAO,CAAC,YAAY,CAAS;gBAEjB,YAAY,EAAE,MAAM;IAI1B,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;YAiDzC,uBAAuB;YAgDvB,0BAA0B;IA6CxC,OAAO,CAAC,kBAAkB;IA6H1B,OAAO,CAAC,eAAe;IA+GvB,OAAO,CAAC,cAAc;IAiDtB,OAAO,CAAC,eAAe;YA6RT,2BAA2B;IA4PzC;;OAEG;YACW,gBAAgB;YAyBhB,gBAAgB;YAuDhB,gBAAgB;IAgF9B;;;OAGG;YACW,kBAAkB;YA2GlB,mBAAmB;IA0iBjC,OAAO,CAAC,mBAAmB;IAS3B;;;OAGG;IACG,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC/D;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAuBzB;;OAEG;IACH,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IA2HtD;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAkB5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archlast/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Archlast CLI for development and deployment",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -9,6 +9,7 @@
9
9
  },
10
10
  "files": [
11
11
  "dist",
12
+ "scripts",
12
13
  "README.md",
13
14
  "LICENSE"
14
15
  ],
@@ -23,6 +24,7 @@
23
24
  "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
24
25
  "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\"",
25
26
  "prepublishOnly": "bun run build",
27
+ "postinstall": "node scripts/postinstall.js",
26
28
  "clean": "rm -rf dist"
27
29
  },
28
30
  "keywords": [
@@ -0,0 +1,65 @@
1
+ const { spawnSync } = require("child_process");
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+
5
+ function bunOnPath() {
6
+ try {
7
+ const result = spawnSync("bun", ["--version"], { stdio: "ignore" });
8
+ return result.status === 0;
9
+ } catch {
10
+ return false;
11
+ }
12
+ }
13
+
14
+ function getBunBin() {
15
+ const home = process.env.USERPROFILE || process.env.HOME;
16
+ if (!home) return null;
17
+ return path.join(home, ".bun", "bin");
18
+ }
19
+
20
+ function pathIncludes(pathValue, target) {
21
+ const normalizedTarget = target.trim().toLowerCase();
22
+ return pathValue
23
+ .split(";")
24
+ .map((entry) => entry.trim().toLowerCase())
25
+ .includes(normalizedTarget);
26
+ }
27
+
28
+ function ensureWindowsBunPath() {
29
+ if (process.platform !== "win32") return;
30
+
31
+ if (bunOnPath()) return;
32
+
33
+ const bunBin = getBunBin();
34
+ if (!bunBin || !fs.existsSync(bunBin)) {
35
+ console.log("[info] Bun not found. Install it from https://bun.sh/");
36
+ return;
37
+ }
38
+
39
+ const pathValue = process.env.Path || process.env.PATH || "";
40
+ if (pathIncludes(pathValue, bunBin)) return;
41
+
42
+ const command = `[Environment]::SetEnvironmentVariable('Path', "$env:Path;${bunBin}", 'User')`;
43
+ const result = spawnSync("powershell.exe", ["-NoProfile", "-Command", command], {
44
+ stdio: "ignore",
45
+ });
46
+
47
+ if (result.status === 0) {
48
+ console.log(`[ok] Added ${bunBin} to user PATH. Restart your terminal.`);
49
+ } else {
50
+ console.log("[warn] Could not update PATH automatically. Run:");
51
+ console.log(`[warn] ${command}`);
52
+ }
53
+ }
54
+
55
+ function run() {
56
+ ensureWindowsBunPath();
57
+ }
58
+
59
+ try {
60
+ run();
61
+ } catch {
62
+ // Never fail the install.
63
+ }
64
+
65
+ process.exit(0);