@chrisluyi/daas-cli 1.5.4 → 1.6.1

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 (2) hide show
  1. package/dist/index.js +132 -24
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -2445,7 +2445,7 @@ function stripScope(name) {
2445
2445
  return name.replace(/^@[^/]+\//, "").replace(/-/g, "_");
2446
2446
  }
2447
2447
  // package.json
2448
- var version = "1.5.4";
2448
+ var version = "1.6.1";
2449
2449
 
2450
2450
  // src/version.ts
2451
2451
  function getCliVersion() {
@@ -3605,7 +3605,6 @@ function getPackageName(cwd) {
3605
3605
  import { spawnSync } from "child_process";
3606
3606
  import { existsSync as existsSync8, readdirSync as readdirSync2, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
3607
3607
  import { relative as relative2, resolve as resolve9 } from "path";
3608
-
3609
3608
  class RegionError extends Error {
3610
3609
  constructor(message) {
3611
3610
  super(message);
@@ -3616,6 +3615,17 @@ var DEFAULT_ALIASES = {
3616
3615
  "@region-config": "./src/config/regions/{region}/config",
3617
3616
  "@regional": "./src/config/regions/{region}/index"
3618
3617
  };
3618
+ var DEFAULT_TARGET_ALIASES = {
3619
+ ...DEFAULT_ALIASES,
3620
+ "@platform-config": "./src/config/platforms/{platform}",
3621
+ "@product-config": "./src/config/products/{product}"
3622
+ };
3623
+ function parseSelector(selector) {
3624
+ if (selector.split("-").length >= 4) {
3625
+ return { selector, ...parseTarget(selector) };
3626
+ }
3627
+ return { selector, region: selector };
3628
+ }
3619
3629
  function readRegionalConfig(cwd = process.cwd()) {
3620
3630
  const pkgPath = resolve9(cwd, "package.json");
3621
3631
  if (!existsSync8(pkgPath)) {
@@ -3626,6 +3636,8 @@ function readRegionalConfig(cwd = process.cwd()) {
3626
3636
  return {
3627
3637
  ...r4,
3628
3638
  regionsDir: r4.regionsDir ?? "src/config/regions",
3639
+ platformsDir: r4.platformsDir ?? "src/config/platforms",
3640
+ productsDir: r4.productsDir ?? "src/config/products",
3629
3641
  tsconfig: r4.tsconfig ?? "tsconfig.daas.json",
3630
3642
  extends: r4.extends ?? "./tsconfig.json",
3631
3643
  bunPaths: r4.bunPaths ?? false
@@ -3644,31 +3656,119 @@ function discoverRegions(cwd, cfg) {
3644
3656
  }
3645
3657
  return regions;
3646
3658
  }
3647
- function renderRegionTsconfig(cwd, cfg, region) {
3659
+ function discoverDimension(cwd, dir, explicit) {
3660
+ const abs = resolve9(cwd, dir);
3661
+ if (!existsSync8(abs))
3662
+ return null;
3663
+ const entries = readdirSync2(abs, { withFileTypes: true }).filter((e3) => e3.isDirectory() || e3.name.endsWith(".ts")).map((e3) => ({
3664
+ name: e3.isDirectory() ? e3.name : e3.name.replace(/\.ts$/, ""),
3665
+ rel: `${dir}/${e3.name}`
3666
+ })).sort((a4, b4) => a4.name.localeCompare(b4.name));
3667
+ if (explicit && explicit.length > 0) {
3668
+ return entries.filter((e3) => explicit.includes(e3.name));
3669
+ }
3670
+ return entries;
3671
+ }
3672
+ function renderRegionTsconfig(cwd, cfg, selectorArg) {
3673
+ const sel = parseSelector(selectorArg);
3648
3674
  const regions = discoverRegions(cwd, cfg);
3649
- if (!regions.includes(region)) {
3650
- throw new RegionError(`Unknown region "${region}". Known: ${regions.join(", ")}`);
3651
- }
3652
- const aliases = cfg.aliases ?? DEFAULT_ALIASES;
3653
- const paths = Object.fromEntries(Object.entries(aliases).map(([k3, v3]) => [
3654
- k3,
3655
- [v3.replaceAll("{region}", region)]
3656
- ]));
3675
+ if (!regions.includes(sel.region)) {
3676
+ throw new RegionError(`Unknown region "${sel.region}". Known: ${regions.join(", ")}`);
3677
+ }
3678
+ const aliases = cfg.aliases ?? (sel.platform ? DEFAULT_TARGET_ALIASES : DEFAULT_ALIASES);
3679
+ const substitutions = {
3680
+ "{region}": sel.region,
3681
+ "{platform}": sel.platform,
3682
+ "{product}": sel.product,
3683
+ "{environment}": sel.environment
3684
+ };
3685
+ const paths = Object.fromEntries(Object.entries(aliases).map(([k3, v3]) => {
3686
+ let out = v3;
3687
+ for (const [ph, value] of Object.entries(substitutions)) {
3688
+ if (!out.includes(ph))
3689
+ continue;
3690
+ if (value === undefined) {
3691
+ throw new RegionError(`Alias "${k3}" uses ${ph} \u2014 pass a full target ({region}-{product}-{platform}-{environment}), not a bare region`);
3692
+ }
3693
+ out = out.replaceAll(ph, value);
3694
+ }
3695
+ return [k3, [out]];
3696
+ }));
3657
3697
  const tsconfigDir = resolve9(cwd, cfg.tsconfig, "..");
3698
+ const toRel = (p) => relative2(tsconfigDir, resolve9(cwd, p));
3699
+ const nonSelected = regions.filter((r4) => r4 !== sel.region);
3700
+ const exclude = nonSelected.map((r4) => toRel(`${cfg.regionsDir}/${r4}`));
3658
3701
  const regionsDirAbs = resolve9(cwd, cfg.regionsDir);
3659
- const others = regions.filter((r4) => r4 !== region).map((r4) => relative2(tsconfigDir, resolve9(regionsDirAbs, r4)));
3660
- const exclude = [...others, ...cfg.multiRegionFiles ?? []];
3702
+ const aliasTreeRoots = new Set;
3703
+ for (const value of Object.values(aliases)) {
3704
+ if (!value.includes("{region}"))
3705
+ continue;
3706
+ let prefix = value.slice(0, value.indexOf("{region}"));
3707
+ let resolvable = true;
3708
+ for (const [ph, v3] of Object.entries(substitutions)) {
3709
+ if (ph === "{region}" || !prefix.includes(ph))
3710
+ continue;
3711
+ if (v3 === undefined) {
3712
+ resolvable = false;
3713
+ break;
3714
+ }
3715
+ prefix = prefix.replaceAll(ph, v3);
3716
+ }
3717
+ if (!resolvable)
3718
+ continue;
3719
+ const rootAbs = resolve9(tsconfigDir, prefix);
3720
+ if (rootAbs !== regionsDirAbs)
3721
+ aliasTreeRoots.add(rootAbs);
3722
+ }
3723
+ for (const rootAbs of aliasTreeRoots) {
3724
+ for (const r4 of nonSelected) {
3725
+ exclude.push(relative2(tsconfigDir, resolve9(rootAbs, r4)));
3726
+ }
3727
+ }
3728
+ const resolveDimDir = (template) => {
3729
+ let out = template;
3730
+ for (const [ph, value] of Object.entries(substitutions)) {
3731
+ if (!out.includes(ph))
3732
+ continue;
3733
+ if (value === undefined)
3734
+ return null;
3735
+ out = out.replaceAll(ph, value);
3736
+ }
3737
+ return out;
3738
+ };
3739
+ for (const [dim, dirTemplate, explicit] of [
3740
+ ["platform", cfg.platformsDir, cfg.platforms],
3741
+ ["product", cfg.productsDir, cfg.products]
3742
+ ]) {
3743
+ const selected = sel[dim];
3744
+ if (!selected)
3745
+ continue;
3746
+ const dir = resolveDimDir(dirTemplate);
3747
+ if (!dir)
3748
+ continue;
3749
+ const entries = discoverDimension(cwd, dir, explicit);
3750
+ if (!entries)
3751
+ continue;
3752
+ if (!entries.some((e3) => e3.name === selected)) {
3753
+ throw new RegionError(`Unknown ${dim} "${selected}". Known: ${entries.map((e3) => e3.name).join(", ")}`);
3754
+ }
3755
+ for (const e3 of entries) {
3756
+ if (e3.name !== selected)
3757
+ exclude.push(toRel(e3.rel));
3758
+ }
3759
+ }
3760
+ exclude.push(...cfg.multiRegionFiles ?? []);
3661
3761
  const compilerOptions = {
3662
3762
  ...cfg.bunPaths ? { baseUrl: ".", ignoreDeprecations: "6.0" } : {},
3663
3763
  paths
3664
3764
  };
3665
3765
  const body = JSON.stringify({ extends: cfg.extends, compilerOptions, exclude }, null, 2);
3666
- return `// GENERATED by \`daas region ${region}\` \u2014 do not edit; regenerate or \`daas region --reset\`.
3766
+ return `// GENERATED by \`daas region ${sel.selector}\` \u2014 do not edit; regenerate or \`daas region --reset\`.
3667
3767
  ${body}
3668
3768
  `;
3669
3769
  }
3670
- function writeRegionTsconfig(cwd, cfg, region, applyTo) {
3671
- const content = renderRegionTsconfig(cwd, cfg, region);
3770
+ function writeRegionTsconfig(cwd, cfg, selector, applyTo) {
3771
+ const content = renderRegionTsconfig(cwd, cfg, selector);
3672
3772
  const out = resolve9(cwd, cfg.tsconfig);
3673
3773
  writeFileSync5(out, content);
3674
3774
  if (applyTo) {
@@ -3695,11 +3795,12 @@ function runRegionCheck(cwd, cfg, runner = (p) => {
3695
3795
  });
3696
3796
  return { ok: r4.status === 0, output: `${r4.stdout ?? ""}${r4.stderr ?? ""}` };
3697
3797
  }) {
3798
+ const selectors = cfg.targets && cfg.targets.length > 0 ? cfg.targets : discoverRegions(cwd, cfg);
3698
3799
  const results = [];
3699
- for (const region of discoverRegions(cwd, cfg)) {
3700
- writeRegionTsconfig(cwd, cfg, region);
3800
+ for (const selector of selectors) {
3801
+ writeRegionTsconfig(cwd, cfg, selector);
3701
3802
  const { ok, output } = runner(resolve9(cwd, cfg.tsconfig));
3702
- results.push({ region, ok, output });
3803
+ results.push({ region: selector, ok, output });
3703
3804
  }
3704
3805
  return results;
3705
3806
  }
@@ -3713,14 +3814,18 @@ var regionCommand = defineCommand({
3713
3814
  args: {
3714
3815
  region: {
3715
3816
  type: "positional",
3716
- description: "Region to select (see --list)",
3817
+ description: "Region, or full target string {region}-{product}-{platform}-{environment} e.g. sg-digibank-shared-dev (see --list)",
3717
3818
  required: false
3718
3819
  },
3719
- list: { type: "boolean", default: false, description: "List regions" },
3820
+ list: {
3821
+ type: "boolean",
3822
+ default: false,
3823
+ description: "List regions (and configured targets)"
3824
+ },
3720
3825
  check: {
3721
3826
  type: "boolean",
3722
3827
  default: false,
3723
- description: "Matrix gate: generate + tsc --noEmit for EVERY region; fails if any region's program fails"
3828
+ description: "Matrix gate: generate + tsc --noEmit per daas.regional.targets entry (else per region); fails if any program fails"
3724
3829
  },
3725
3830
  apply: {
3726
3831
  type: "string",
@@ -3751,9 +3856,12 @@ var regionCommand = defineCommand({
3751
3856
  if (args.list) {
3752
3857
  const regions = discoverRegions(cwd, cfg);
3753
3858
  if (args.json)
3754
- writeJsonSuccess("region", { regions });
3755
- else
3859
+ writeJsonSuccess("region", { regions, targets: cfg.targets ?? [] });
3860
+ else {
3756
3861
  consola.info(`Regions: ${regions.join(", ")}`);
3862
+ if (cfg.targets && cfg.targets.length > 0)
3863
+ consola.info(`Targets: ${cfg.targets.join(", ")}`);
3864
+ }
3757
3865
  return;
3758
3866
  }
3759
3867
  if (args.check) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrisluyi/daas-cli",
3
- "version": "1.5.4",
3
+ "version": "1.6.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "daas": "./dist/index.js"
@@ -22,8 +22,8 @@
22
22
  "dependencies": {
23
23
  "@clack/prompts": "^0.7.0",
24
24
  "@chrisluyi/daas-logger": "1.1.1",
25
- "@chrisluyi/daas-rsbuild-config": "1.5.4",
26
- "@chrisluyi/daas-template": "1.5.4",
25
+ "@chrisluyi/daas-rsbuild-config": "1.6.1",
26
+ "@chrisluyi/daas-template": "1.6.1",
27
27
  "@rsbuild/core": "*",
28
28
  "citty": "^0.1.6",
29
29
  "consola": "^3.2.3",