@uniformdev/cli 18.17.1-alpha.13 → 18.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -18,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
18
18
  return to;
19
19
  };
20
20
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
25
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
26
  mod
23
27
  ));
@@ -886,6 +890,8 @@ var require_route = __commonJS({
886
890
  const models = Object.keys(conversions);
887
891
  for (let len = models.length, i = 0; i < len; i++) {
888
892
  graph[models[i]] = {
893
+ // http://jsperf.com/1-vs-infinity
894
+ // micro-opt, but this is simple.
889
895
  distance: -1,
890
896
  parent: null
891
897
  };
@@ -1061,6 +1067,7 @@ var require_ansi_styles = __commonJS({
1061
1067
  const styles = {
1062
1068
  modifier: {
1063
1069
  reset: [0, 0],
1070
+ // 21 isn't widely supported and 22 does the same thing
1064
1071
  bold: [1, 22],
1065
1072
  dim: [2, 22],
1066
1073
  italic: [3, 23],
@@ -1078,6 +1085,7 @@ var require_ansi_styles = __commonJS({
1078
1085
  magenta: [35, 39],
1079
1086
  cyan: [36, 39],
1080
1087
  white: [37, 39],
1088
+ // Bright color
1081
1089
  blackBright: [90, 39],
1082
1090
  redBright: [91, 39],
1083
1091
  greenBright: [92, 39],
@@ -1096,6 +1104,7 @@ var require_ansi_styles = __commonJS({
1096
1104
  bgMagenta: [45, 49],
1097
1105
  bgCyan: [46, 49],
1098
1106
  bgWhite: [47, 49],
1107
+ // Bright color
1099
1108
  bgBlackBright: [100, 49],
1100
1109
  bgRedBright: [101, 49],
1101
1110
  bgGreenBright: [102, 49],
@@ -1664,7 +1673,13 @@ function withApiOptions(yargs18) {
1664
1673
  var _a, _b, _c;
1665
1674
  return yargs18.option("apiKey", {
1666
1675
  describe: "Uniform API key. Defaults to UNIFORM_CLI_API_KEY or UNIFORM_API_KEY env. Supports dotenv.",
1667
- default: (_c = (_b = (_a = process.env.UNIFORM_CLI_API_KEY) != null ? _a : process.env.CANVAS_CLI_API_KEY) != null ? _b : process.env.UPM_CLI_API_KEY) != null ? _c : process.env.UNIFORM_API_KEY,
1676
+ default: (_c = (_b = (_a = process.env.UNIFORM_CLI_API_KEY) != null ? _a : (
1677
+ // deprecated
1678
+ process.env.CANVAS_CLI_API_KEY
1679
+ )) != null ? _b : (
1680
+ // deprecated
1681
+ process.env.UPM_CLI_API_KEY
1682
+ )) != null ? _c : process.env.UNIFORM_API_KEY,
1668
1683
  demandOption: true,
1669
1684
  type: "string"
1670
1685
  }).option("apiHost", {
@@ -1703,7 +1718,13 @@ function withProjectOptions(yargs18) {
1703
1718
  var _a, _b, _c;
1704
1719
  return yargs18.option("project", {
1705
1720
  describe: "Uniform project ID. Defaults to UNIFORM_CLI_PROJECT_ID or UNIFORM_PROJECT_ID env. Supports dotenv.",
1706
- default: (_c = (_b = (_a = process.env.UNIFORM_CLI_PROJECT_ID) != null ? _a : process.env.CANVAS_CLI_PROJECT_ID) != null ? _b : process.env.UPM_CLI_PROJECT_ID) != null ? _c : process.env.UNIFORM_PROJECT_ID,
1721
+ default: (_c = (_b = (_a = process.env.UNIFORM_CLI_PROJECT_ID) != null ? _a : (
1722
+ // deprecated
1723
+ process.env.CANVAS_CLI_PROJECT_ID
1724
+ )) != null ? _b : (
1725
+ // deprecated
1726
+ process.env.UPM_CLI_PROJECT_ID
1727
+ )) != null ? _c : process.env.UNIFORM_PROJECT_ID,
1707
1728
  demandOption: true,
1708
1729
  type: "string",
1709
1730
  alias: ["p"]
@@ -1867,6 +1888,7 @@ async function syncEngine({
1867
1888
  mode,
1868
1889
  allowEmptySource = false,
1869
1890
  whatIf = false,
1891
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
1870
1892
  log = () => {
1871
1893
  }
1872
1894
  }) {
@@ -2523,6 +2545,10 @@ var CompositionListModule = {
2523
2545
  default: false,
2524
2546
  describe: "Resolve pattern references in the composition"
2525
2547
  },
2548
+ resolveOverrides: {
2549
+ type: "boolean",
2550
+ default: false
2551
+ },
2526
2552
  componentIDs: {
2527
2553
  type: "boolean",
2528
2554
  default: false,
@@ -2544,6 +2570,7 @@ var CompositionListModule = {
2544
2570
  project: projectId,
2545
2571
  state,
2546
2572
  resolvePatterns,
2573
+ resolveOverrides,
2547
2574
  componentIDs
2548
2575
  }) => {
2549
2576
  const fetch3 = nodeFetchProxy(proxy);
@@ -2553,7 +2580,8 @@ var CompositionListModule = {
2553
2580
  offset,
2554
2581
  state: convertCompositionState(state),
2555
2582
  skipPatternResolution: !resolvePatterns,
2556
- withComponentIDs: componentIDs
2583
+ withComponentIDs: componentIDs,
2584
+ skipParameterResolution: !resolveOverrides
2557
2585
  });
2558
2586
  emitWithFormat(res.compositions, format, filename);
2559
2587
  }
@@ -2585,6 +2613,7 @@ function createComponentInstanceEngineDataSource({
2585
2613
  state: stateId,
2586
2614
  skipPatternResolution: true,
2587
2615
  skipParameterResolution: true,
2616
+ skipOverridesResolution: true,
2588
2617
  withComponentIDs: true
2589
2618
  })).compositions,
2590
2619
  { pageSize: 100 }
@@ -2900,6 +2929,7 @@ var DataTypeGetModule = {
2900
2929
  builder: (yargs18) => withFormatOptions(
2901
2930
  withApiOptions(
2902
2931
  withProjectOptions(
2932
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2903
2933
  yargs18.positional("id", { demandOption: true, describe: "Data type public ID to fetch" })
2904
2934
  )
2905
2935
  )
@@ -4717,104 +4747,189 @@ var ContextCommand = {
4717
4747
  }
4718
4748
  };
4719
4749
 
4720
- // src/commands/new/commands/new.ts
4721
- var import_inquirer4 = __toESM(require("inquirer"));
4722
-
4723
- // src/commands/new/actions/chooseTeam.ts
4724
- var import_inquirer = __toESM(require("inquirer"));
4725
- async function chooseTeam(user, prompt, telemetry) {
4726
- const result = await import_inquirer.default.prompt([
4727
- {
4728
- type: "list",
4729
- name: "teamId",
4730
- message: prompt,
4731
- choices: user.teams.map((team) => ({
4732
- name: team.team.name,
4733
- value: team.team.id
4734
- }))
4735
- }
4736
- ]);
4737
- telemetry.send("team picked", { teamId: result.teamId });
4738
- return result;
4739
- }
4750
+ // src/spinner.ts
4751
+ var makeSpinner = () => {
4752
+ const spinners = [];
4753
+ const stopAllSpinners = () => spinners.forEach((spinner) => spinner.stop());
4754
+ const spin = async (text) => {
4755
+ const spinner = await Promise.resolve().then(() => __toESM(require("ora"))).then((ora) => ora.default(text).start());
4756
+ spinners.push(spinner);
4757
+ const minWait = new Promise((resolve) => setTimeout(resolve, 500));
4758
+ return async () => {
4759
+ await minWait;
4760
+ spinner.stop();
4761
+ };
4762
+ };
4763
+ return { stopAllSpinners, spin };
4764
+ };
4740
4765
 
4741
- // src/commands/new/actions/cloneStarter.ts
4766
+ // src/telemetry/telemetry.ts
4742
4767
  var import_crypto = __toESM(require("crypto"));
4743
- var import_fs6 = __toESM(require("fs"));
4744
- var import_fs_jetpack = require("fs-jetpack");
4745
- var git = __toESM(require("isomorphic-git"));
4746
- var http = __toESM(require("isomorphic-git/http/node"));
4747
- var import_os = __toESM(require("os"));
4748
- var import_path3 = __toESM(require("path"));
4768
+ var import_posthog_node = require("posthog-node");
4749
4769
 
4750
- // src/commands/new/npm.ts
4751
- var import_execa = __toESM(require("execa"));
4752
- var runNpm = async (workDir, args, { inherit, env } = {}) => {
4753
- let result;
4754
- try {
4755
- result = await (0, import_execa.default)("npm", args, {
4756
- cwd: workDir,
4757
- env: env != null ? env : {},
4758
- ...inherit ? { stdout: "inherit", stderr: "inherit" } : {}
4759
- });
4760
- } catch (err) {
4761
- throw new Error(`Failed to execute npm ${args.join(" ")}
4762
- ${err.message}`);
4763
- }
4764
- if (result.exitCode !== 0) {
4765
- throw new Error(`Command npm ${args.join(" ")} exitted with code ${result == null ? void 0 : result.exitCode}}: ${result.stderr}`);
4770
+ // package.json
4771
+ var package_default = {
4772
+ name: "@uniformdev/cli",
4773
+ version: "18.19.0",
4774
+ description: "Uniform command line interface tool",
4775
+ license: "SEE LICENSE IN LICENSE.txt",
4776
+ main: "./cli.js",
4777
+ types: "./dist/index.d.ts",
4778
+ sideEffects: false,
4779
+ scripts: {
4780
+ uniform: "node ./cli.js",
4781
+ build: "tsup",
4782
+ dev: "tsup --watch",
4783
+ clean: "rimraf dist",
4784
+ test: "jest --maxWorkers=1 --passWithNoTests",
4785
+ lint: 'eslint "src/**/*.{js,ts,tsx}"',
4786
+ format: 'prettier --write "src/**/*.{js,ts,tsx}"'
4787
+ },
4788
+ dependencies: {
4789
+ "@uniformdev/canvas": "workspace:*",
4790
+ "@uniformdev/context": "workspace:*",
4791
+ "@uniformdev/project-map": "workspace:*",
4792
+ diff: "^5.0.0",
4793
+ dotenv: "^16.0.3",
4794
+ execa: "5.1.1",
4795
+ "fs-jetpack": "5.1.0",
4796
+ graphql: "16.6.0",
4797
+ "graphql-request": "5.1.0",
4798
+ "https-proxy-agent": "^5.0.1",
4799
+ inquirer: "8.2.5",
4800
+ "isomorphic-git": "1.21.0",
4801
+ "isomorphic-unfetch": "^3.1.0",
4802
+ "js-yaml": "^4.1.0",
4803
+ jsonwebtoken: "9.0.0",
4804
+ "lodash.isequalwith": "^4.4.0",
4805
+ open: "8.4.0",
4806
+ ora: "6.1.2",
4807
+ "posthog-node": "2.5.3",
4808
+ slugify: "1.6.5",
4809
+ yargs: "^17.6.2",
4810
+ zod: "3.20.6"
4811
+ },
4812
+ devDependencies: {
4813
+ "@types/diff": "5.0.2",
4814
+ "@types/inquirer": "9.0.3",
4815
+ "@types/js-yaml": "4.0.5",
4816
+ "@types/jsonwebtoken": "9.0.1",
4817
+ "@types/lodash.isequalwith": "4.4.7",
4818
+ "@types/node": "18.11.17",
4819
+ "@types/yargs": "17.0.22",
4820
+ "p-limit": "4.0.0"
4821
+ },
4822
+ bin: {
4823
+ uniform: "./cli.js"
4824
+ },
4825
+ files: [
4826
+ "/dist"
4827
+ ],
4828
+ publishConfig: {
4829
+ access: "public"
4766
4830
  }
4767
- return result.stdout;
4768
4831
  };
4769
4832
 
4770
- // src/commands/new/actions/cloneStarter.ts
4771
- async function cloneStarter({
4772
- spin,
4773
- githubPath,
4774
- targetDir,
4775
- dotEnvFile
4776
- }) {
4777
- const done = await spin("Fetching starter code...");
4778
- const cloneDir = import_path3.default.join(import_os.default.tmpdir(), `uniform-new-${import_crypto.default.randomBytes(20).toString("hex")}`);
4779
- const [user, repo, ...pathSegments] = githubPath.split("/");
4780
- try {
4781
- await git.clone({
4782
- fs: import_fs6.default,
4783
- http,
4784
- url: `https://github.com/${user}/${repo}`,
4785
- dir: cloneDir,
4786
- singleBranch: true,
4787
- depth: 1
4833
+ // src/telemetry/telemetry.ts
4834
+ var POSTHOG_WRITE_ONLY_KEY = "phc_c8YoKI9984KOHBfNrCRfIKvL56aYd5OpYxOdYexRzH7";
4835
+ var Telemetry = class {
4836
+ constructor(prefix, disable = false) {
4837
+ this.prefix = prefix;
4838
+ this.distinctId = import_crypto.default.randomBytes(20).toString("hex");
4839
+ if (!disable) {
4840
+ this.posthog = new import_posthog_node.PostHog(POSTHOG_WRITE_ONLY_KEY, {
4841
+ flushAt: 1,
4842
+ flushInterval: 1
4843
+ });
4844
+ this.send("started");
4845
+ }
4846
+ }
4847
+ login(sub, user) {
4848
+ if (!this.posthog) {
4849
+ return;
4850
+ }
4851
+ const alias = this.distinctId;
4852
+ this.distinctId = sub;
4853
+ this.posthog.alias({ distinctId: this.distinctId, alias });
4854
+ this.posthog.identify({
4855
+ distinctId: this.distinctId,
4856
+ properties: {
4857
+ email: user.email_address,
4858
+ sub,
4859
+ teamCount: user.teams.length
4860
+ }
4788
4861
  });
4789
- } catch (err) {
4790
- throw new Error(`Failed to fetch starter code: ${err.message}`);
4862
+ this.send("logged in");
4791
4863
  }
4792
- await done();
4793
- if (import_fs6.default.existsSync(targetDir) && import_fs6.default.readdirSync(targetDir).length > 0) {
4794
- throw new Error(`"${targetDir}" is not empty`);
4864
+ send(event, properties = {}) {
4865
+ var _a;
4866
+ (_a = this.posthog) == null ? void 0 : _a.capture({
4867
+ distinctId: this.distinctId,
4868
+ event: [this.prefix, event].join(" "),
4869
+ properties: {
4870
+ version: package_default.version,
4871
+ ...properties
4872
+ }
4873
+ });
4795
4874
  }
4796
- const starterDir = import_path3.default.join(cloneDir, ...pathSegments);
4797
- (0, import_fs_jetpack.copy)(starterDir, targetDir, { overwrite: true });
4798
- if (dotEnvFile) {
4799
- import_fs6.default.writeFileSync(import_path3.default.resolve(targetDir, ".env"), dotEnvFile, "utf-8");
4875
+ shutdown() {
4876
+ var _a;
4877
+ this.send("exited", { exitCode: process.exitCode });
4878
+ return (_a = this.posthog) == null ? void 0 : _a.shutdownAsync();
4800
4879
  }
4801
- console.log(`
4802
- Your project now lives in ${targetDir} \u2728`);
4803
- return {
4804
- runNpmInstall: async () => {
4805
- console.log(`
4806
- Installing project dependencies...
4880
+ };
4807
4881
 
4808
- `);
4809
- await runNpm(targetDir, ["i"], { inherit: true });
4882
+ // src/commands/new/commands/new.ts
4883
+ var import_inquirer4 = __toESM(require("inquirer"));
4884
+
4885
+ // src/auth/getBearerToken.ts
4886
+ var import_inquirer = __toESM(require("inquirer"));
4887
+ var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
4888
+ var import_open = __toESM(require("open"));
4889
+
4890
+ // src/url.ts
4891
+ var makeUrl = (baseUrl, path4) => [baseUrl.trim().replace(/\/+$/, ""), path4.trim().replace(/^\/+/, "")].join("/");
4892
+
4893
+ // src/auth/getBearerToken.ts
4894
+ async function getBearerToken(baseUrl) {
4895
+ const { canOpen } = await import_inquirer.default.prompt([
4896
+ {
4897
+ type: "confirm",
4898
+ name: "canOpen",
4899
+ message: "Can we open a browser window to get a Uniform auth token?"
4900
+ }
4901
+ ]);
4902
+ if (canOpen) {
4903
+ (0, import_open.default)(makeUrl(baseUrl, "/cli-login"));
4904
+ }
4905
+ const tokenAnswer = await import_inquirer.default.prompt([
4906
+ {
4907
+ type: "password",
4908
+ name: "authToken",
4909
+ message: "Paste your Uniform auth token"
4810
4910
  }
4911
+ ]);
4912
+ const authToken = tokenAnswer.authToken.trim();
4913
+ if (!authToken) {
4914
+ throw new Error("No auth token provided.");
4915
+ }
4916
+ const decoded = import_jsonwebtoken.default.decode(authToken, { complete: false });
4917
+ if (!decoded) {
4918
+ throw new Error("Could not parse the token pasted.");
4919
+ }
4920
+ if (typeof decoded.sub !== "string" || typeof decoded === "string") {
4921
+ throw new Error("Invalid token pasted.");
4922
+ }
4923
+ return {
4924
+ authToken,
4925
+ decoded: { ...decoded, sub: decoded.sub }
4811
4926
  };
4812
4927
  }
4813
4928
 
4814
- // src/commands/new/client.ts
4929
+ // src/client.ts
4815
4930
  var import_zod = require("zod");
4816
4931
 
4817
- // src/commands/new/api-key.ts
4932
+ // src/auth/api-key.ts
4818
4933
  var READ_PERMISSIONS = ["PROJECT", "UPM_PUB", "OPT_PUB", "OPT_READ", "UPM_READ"];
4819
4934
  var WRITE_PERMISSIONS = [
4820
4935
  "PROJECT",
@@ -4862,10 +4977,7 @@ var makeApiKey = (teamId, projectId, name, permissions) => ({
4862
4977
  var makeReadApiKey = (teamId, projectId) => makeApiKey(teamId, projectId, "Created by Uniform New (read)", READ_PERMISSIONS);
4863
4978
  var makeWriteApiKey = (teamId, projectId) => makeApiKey(teamId, projectId, "Created by Uniform New (write)", WRITE_PERMISSIONS);
4864
4979
 
4865
- // src/commands/new/url.ts
4866
- var makeUrl = (baseUrl, path4) => [baseUrl.trim().replace(/\/+$/, ""), path4.trim().replace(/^\/+/, "")].join("/");
4867
-
4868
- // src/commands/new/client.ts
4980
+ // src/client.ts
4869
4981
  var createTeamOrProjectSchema = import_zod.z.object({ id: import_zod.z.string().min(1) });
4870
4982
  var createApiKeySchema = import_zod.z.object({ apiKey: import_zod.z.string().min(1) });
4871
4983
  var getLimitsSchema = import_zod.z.object({
@@ -5008,124 +5120,80 @@ var createClient = (baseUrl, authToken) => {
5008
5120
  };
5009
5121
  };
5010
5122
 
5011
- // src/commands/new/user-info.ts
5012
- var import_graphql_request = require("graphql-request");
5013
- var import_zod2 = require("zod");
5014
- var query = import_graphql_request.gql`
5015
- query GetUserInfo($subject: String!) {
5016
- info: identities_by_pk(subject: $subject) {
5017
- name
5018
- email_address
5019
- teams: organizations_identities {
5020
- team: organization {
5021
- name
5022
- id
5023
- sites {
5024
- name
5025
- id
5026
- }
5027
- }
5028
- }
5029
- }
5030
- }
5031
- `;
5032
- var schema = import_zod2.z.object({
5033
- info: import_zod2.z.object({
5034
- name: import_zod2.z.string().min(1),
5035
- email_address: import_zod2.z.string().min(1),
5036
- teams: import_zod2.z.array(
5037
- import_zod2.z.object({
5038
- team: import_zod2.z.object({
5039
- name: import_zod2.z.string().min(1),
5040
- id: import_zod2.z.string().min(1),
5041
- sites: import_zod2.z.array(
5042
- import_zod2.z.object({
5043
- name: import_zod2.z.string().min(1),
5044
- id: import_zod2.z.string().min(1)
5045
- })
5046
- )
5047
- })
5048
- })
5049
- )
5050
- })
5051
- });
5052
- var getUserInfo = async (baseUrl, authToken, subject) => {
5123
+ // src/npm.ts
5124
+ var import_execa = __toESM(require("execa"));
5125
+ var runNpm = async (workDir, args, { inherit, env } = {}) => {
5126
+ let result;
5053
5127
  try {
5054
- const endpoint = makeUrl(baseUrl, "/v1/graphql");
5055
- const res = await (0, import_graphql_request.request)(endpoint, query, { subject }, { Authorization: `Bearer ${authToken}` });
5056
- const parseResult = schema.safeParse(res);
5057
- if (parseResult.success) {
5058
- return parseResult.data.info;
5059
- } else {
5060
- throw new Error(`Invalid GraphQL response: ${parseResult.error.message}`);
5061
- }
5128
+ result = await (0, import_execa.default)("npm", args, {
5129
+ cwd: workDir,
5130
+ env: env != null ? env : {},
5131
+ ...inherit ? { stdout: "inherit", stderr: "inherit" } : {}
5132
+ });
5062
5133
  } catch (err) {
5063
- throw new Error(`Failed to fetch user account:
5064
- ${err.message}`);
5134
+ throw new Error(`Failed to execute npm ${args.join(" ")}
5135
+ ${err.message}`);
5065
5136
  }
5137
+ if (result.exitCode !== 0) {
5138
+ throw new Error(`Command npm ${args.join(" ")} exitted with code ${result == null ? void 0 : result.exitCode}}: ${result.stderr}`);
5139
+ }
5140
+ return result.stdout;
5066
5141
  };
5067
5142
 
5068
- // src/commands/new/actions/fetchUserAndEnsureTeamExists.ts
5069
- async function fetchUserAndEnsureFirstTeamExists({
5070
- baseUrl,
5071
- auth: { authToken, decoded },
5143
+ // src/projects/cloneStarter.ts
5144
+ var import_crypto2 = __toESM(require("crypto"));
5145
+ var import_fs6 = __toESM(require("fs"));
5146
+ var import_fs_jetpack = require("fs-jetpack");
5147
+ var git = __toESM(require("isomorphic-git"));
5148
+ var http = __toESM(require("isomorphic-git/http/node"));
5149
+ var import_os = __toESM(require("os"));
5150
+ var import_path3 = __toESM(require("path"));
5151
+ async function cloneStarter({
5072
5152
  spin,
5073
- telemetry
5153
+ githubPath,
5154
+ targetDir,
5155
+ dotEnvFile
5074
5156
  }) {
5075
- const uniformClient = createClient(baseUrl, authToken);
5076
- const done = await spin("Fetching user information...");
5077
- let user = await getUserInfo(baseUrl, authToken, decoded.sub);
5078
- if (user.teams.length < 1) {
5079
- await uniformClient.createTeam(`${user.name}'s team`);
5080
- user = await getUserInfo(baseUrl, authToken, decoded.sub);
5157
+ const done = await spin("Fetching starter code...");
5158
+ const cloneDir = import_path3.default.join(import_os.default.tmpdir(), `uniform-new-${import_crypto2.default.randomBytes(20).toString("hex")}`);
5159
+ const [user, repo, ...pathSegments] = githubPath.split("/");
5160
+ try {
5161
+ await git.clone({
5162
+ fs: import_fs6.default,
5163
+ http,
5164
+ url: `https://github.com/${user}/${repo}`,
5165
+ dir: cloneDir,
5166
+ singleBranch: true,
5167
+ depth: 1
5168
+ });
5169
+ } catch (err) {
5170
+ throw new Error(`Failed to fetch starter code: ${err.message}`);
5081
5171
  }
5082
5172
  await done();
5083
- telemetry.login(decoded.sub, user);
5084
- return user;
5085
- }
5086
-
5087
- // src/commands/new/actions/getBearerToken.ts
5088
- var import_inquirer2 = __toESM(require("inquirer"));
5089
- var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
5090
- var import_open = __toESM(require("open"));
5091
- async function getBearerToken(baseUrl) {
5092
- const { canOpen } = await import_inquirer2.default.prompt([
5093
- {
5094
- type: "confirm",
5095
- name: "canOpen",
5096
- message: "Can we open a browser window to get a Uniform auth token?"
5097
- }
5098
- ]);
5099
- if (canOpen) {
5100
- (0, import_open.default)(makeUrl(baseUrl, "/cli-login"));
5101
- }
5102
- const tokenAnswer = await import_inquirer2.default.prompt([
5103
- {
5104
- type: "password",
5105
- name: "authToken",
5106
- message: "Paste your Uniform auth token"
5107
- }
5108
- ]);
5109
- const authToken = tokenAnswer.authToken.trim();
5110
- if (!authToken) {
5111
- throw new Error("No auth token provided.");
5112
- }
5113
- const decoded = import_jsonwebtoken.default.decode(authToken, { complete: false });
5114
- if (!decoded) {
5115
- throw new Error("Could not parse the token pasted.");
5173
+ if (import_fs6.default.existsSync(targetDir) && import_fs6.default.readdirSync(targetDir).length > 0) {
5174
+ throw new Error(`"${targetDir}" is not empty`);
5116
5175
  }
5117
- if (typeof decoded.sub !== "string" || typeof decoded === "string") {
5118
- throw new Error("Invalid token pasted.");
5176
+ const starterDir = import_path3.default.join(cloneDir, ...pathSegments);
5177
+ (0, import_fs_jetpack.copy)(starterDir, targetDir, { overwrite: true });
5178
+ if (dotEnvFile) {
5179
+ import_fs6.default.writeFileSync(import_path3.default.resolve(targetDir, ".env"), dotEnvFile, "utf-8");
5119
5180
  }
5181
+ console.log(`
5182
+ Your project now lives in ${targetDir} \u2728`);
5120
5183
  return {
5121
- authToken,
5122
- decoded: { ...decoded, sub: decoded.sub }
5184
+ runNpmInstall: async () => {
5185
+ console.log(`
5186
+ Installing project dependencies...
5187
+
5188
+ `);
5189
+ await runNpm(targetDir, ["i"], { inherit: true });
5190
+ }
5123
5191
  };
5124
5192
  }
5125
5193
 
5126
- // src/commands/new/actions/getOrCreateProject.ts
5194
+ // src/projects/getOrCreateProject.ts
5127
5195
  var import_fs7 = __toESM(require("fs"));
5128
- var import_inquirer3 = __toESM(require("inquirer"));
5196
+ var import_inquirer2 = __toESM(require("inquirer"));
5129
5197
  var import_path4 = __toESM(require("path"));
5130
5198
  var import_slugify = __toESM(require("slugify"));
5131
5199
  var newProjectId = "$new";
@@ -5183,7 +5251,7 @@ async function getNewProjectName({
5183
5251
  }) {
5184
5252
  let projectName = explicitName;
5185
5253
  if (!projectName) {
5186
- const answer = await import_inquirer3.default.prompt([
5254
+ const answer = await import_inquirer2.default.prompt([
5187
5255
  {
5188
5256
  type: "input",
5189
5257
  name: "name",
@@ -5227,7 +5295,7 @@ async function chooseExistingProject({
5227
5295
  value: t.id
5228
5296
  }));
5229
5297
  const choices = createNew ? [{ name: "Create new project...", value: newProjectId }].concat(projects) : projects;
5230
- const result = await import_inquirer3.default.prompt([
5298
+ const result = await import_inquirer2.default.prompt([
5231
5299
  {
5232
5300
  type: "list",
5233
5301
  name: "projectId",
@@ -5261,6 +5329,100 @@ function validateProjectName(projectName, checkTargetDir, explicitTargetDir) {
5261
5329
  }
5262
5330
  }
5263
5331
 
5332
+ // src/teams/chooseTeam.ts
5333
+ var import_inquirer3 = __toESM(require("inquirer"));
5334
+ async function chooseTeam(user, prompt, telemetry) {
5335
+ const result = await import_inquirer3.default.prompt([
5336
+ {
5337
+ type: "list",
5338
+ name: "teamId",
5339
+ message: prompt,
5340
+ choices: user.teams.map((team) => ({
5341
+ name: team.team.name,
5342
+ value: team.team.id
5343
+ }))
5344
+ }
5345
+ ]);
5346
+ telemetry.send("team picked", { teamId: result.teamId });
5347
+ return result;
5348
+ }
5349
+
5350
+ // src/auth/user-info.ts
5351
+ var import_graphql_request = require("graphql-request");
5352
+ var import_zod2 = require("zod");
5353
+ var query = import_graphql_request.gql`
5354
+ query GetUserInfo($subject: String!) {
5355
+ info: identities_by_pk(subject: $subject) {
5356
+ name
5357
+ email_address
5358
+ teams: organizations_identities {
5359
+ team: organization {
5360
+ name
5361
+ id
5362
+ sites {
5363
+ name
5364
+ id
5365
+ }
5366
+ }
5367
+ }
5368
+ }
5369
+ }
5370
+ `;
5371
+ var schema = import_zod2.z.object({
5372
+ info: import_zod2.z.object({
5373
+ name: import_zod2.z.string().min(1),
5374
+ email_address: import_zod2.z.string().min(1),
5375
+ teams: import_zod2.z.array(
5376
+ import_zod2.z.object({
5377
+ team: import_zod2.z.object({
5378
+ name: import_zod2.z.string().min(1),
5379
+ id: import_zod2.z.string().min(1),
5380
+ sites: import_zod2.z.array(
5381
+ import_zod2.z.object({
5382
+ name: import_zod2.z.string().min(1),
5383
+ id: import_zod2.z.string().min(1)
5384
+ })
5385
+ )
5386
+ })
5387
+ })
5388
+ )
5389
+ })
5390
+ });
5391
+ var getUserInfo = async (baseUrl, authToken, subject) => {
5392
+ try {
5393
+ const endpoint = makeUrl(baseUrl, "/v1/graphql");
5394
+ const res = await (0, import_graphql_request.request)(endpoint, query, { subject }, { Authorization: `Bearer ${authToken}` });
5395
+ const parseResult = schema.safeParse(res);
5396
+ if (parseResult.success) {
5397
+ return parseResult.data.info;
5398
+ } else {
5399
+ throw new Error(`Invalid GraphQL response: ${parseResult.error.message}`);
5400
+ }
5401
+ } catch (err) {
5402
+ throw new Error(`Failed to fetch user account:
5403
+ ${err.message}`);
5404
+ }
5405
+ };
5406
+
5407
+ // src/teams/fetchUserAndEnsureTeamExists.ts
5408
+ async function fetchUserAndEnsureFirstTeamExists({
5409
+ baseUrl,
5410
+ auth: { authToken, decoded },
5411
+ spin,
5412
+ telemetry
5413
+ }) {
5414
+ const uniformClient = createClient(baseUrl, authToken);
5415
+ const done = await spin("Fetching user information...");
5416
+ let user = await getUserInfo(baseUrl, authToken, decoded.sub);
5417
+ if (user.teams.length < 1) {
5418
+ await uniformClient.createTeam(`${user.name}'s team`);
5419
+ user = await getUserInfo(baseUrl, authToken, decoded.sub);
5420
+ }
5421
+ await done();
5422
+ telemetry.login(decoded.sub, user);
5423
+ return user;
5424
+ }
5425
+
5264
5426
  // src/commands/new/commands/new.ts
5265
5427
  async function newHandler({
5266
5428
  spin,
@@ -5492,138 +5654,6 @@ function validateIntegrationName(integrationName, explicitOutputPath) {
5492
5654
  return { targetDir, typeSlug };
5493
5655
  }
5494
5656
 
5495
- // src/commands/new/spinner.ts
5496
- var makeSpinner = () => {
5497
- const spinners = [];
5498
- const stopAllSpinners = () => spinners.forEach((spinner) => spinner.stop());
5499
- const spin = async (text) => {
5500
- const spinner = await Promise.resolve().then(() => __toESM(require("ora"))).then((ora) => ora.default(text).start());
5501
- spinners.push(spinner);
5502
- const minWait = new Promise((resolve) => setTimeout(resolve, 500));
5503
- return async () => {
5504
- await minWait;
5505
- spinner.stop();
5506
- };
5507
- };
5508
- return { stopAllSpinners, spin };
5509
- };
5510
-
5511
- // src/commands/new/telemetry.ts
5512
- var import_crypto2 = __toESM(require("crypto"));
5513
- var import_posthog_node = require("posthog-node");
5514
-
5515
- // package.json
5516
- var package_default = {
5517
- name: "@uniformdev/cli",
5518
- version: "18.17.0",
5519
- description: "Uniform command line interface tool",
5520
- license: "SEE LICENSE IN LICENSE.txt",
5521
- main: "./cli.js",
5522
- types: "./dist/index.d.ts",
5523
- sideEffects: false,
5524
- scripts: {
5525
- uniform: "node ./cli.js",
5526
- build: "tsup",
5527
- dev: "tsup --watch",
5528
- clean: "rimraf dist",
5529
- test: "jest --maxWorkers=1 --passWithNoTests",
5530
- lint: 'eslint "src/**/*.{js,ts,tsx}"',
5531
- format: 'prettier --write "src/**/*.{js,ts,tsx}"'
5532
- },
5533
- dependencies: {
5534
- "@uniformdev/canvas": "workspace:*",
5535
- "@uniformdev/context": "workspace:*",
5536
- "@uniformdev/project-map": "workspace:*",
5537
- execa: "5.1.1",
5538
- "fs-jetpack": "5.1.0",
5539
- graphql: "16.6.0",
5540
- "graphql-request": "5.1.0",
5541
- inquirer: "8.2.5",
5542
- "isomorphic-git": "1.21.0",
5543
- jsonwebtoken: "9.0.0",
5544
- open: "8.4.0",
5545
- ora: "6.1.2",
5546
- "posthog-node": "2.2.3",
5547
- slugify: "1.6.5",
5548
- diff: "^5.0.0",
5549
- dotenv: "^16.0.3",
5550
- "https-proxy-agent": "^5.0.1",
5551
- "isomorphic-unfetch": "^3.1.0",
5552
- "js-yaml": "^4.1.0",
5553
- "lodash.isequalwith": "^4.4.0",
5554
- yargs: "^17.6.2",
5555
- zod: "3.20.2"
5556
- },
5557
- devDependencies: {
5558
- "@types/inquirer": "9.0.3",
5559
- "@types/jsonwebtoken": "9.0.1",
5560
- "@types/node": "18.11.17",
5561
- "@types/diff": "5.0.2",
5562
- "@types/js-yaml": "4.0.5",
5563
- "@types/lodash.isequalwith": "4.4.7",
5564
- "@types/yargs": "17.0.22",
5565
- "p-limit": "4.0.0"
5566
- },
5567
- bin: {
5568
- uniform: "./cli.js"
5569
- },
5570
- files: [
5571
- "/dist"
5572
- ],
5573
- publishConfig: {
5574
- access: "public"
5575
- }
5576
- };
5577
-
5578
- // src/commands/new/telemetry.ts
5579
- var POSTHOG_WRITE_ONLY_KEY = "phc_c8YoKI9984KOHBfNrCRfIKvL56aYd5OpYxOdYexRzH7";
5580
- var Telemetry = class {
5581
- constructor(prefix, disable = false) {
5582
- this.prefix = prefix;
5583
- this.distinctId = import_crypto2.default.randomBytes(20).toString("hex");
5584
- if (!disable) {
5585
- this.posthog = new import_posthog_node.PostHog(POSTHOG_WRITE_ONLY_KEY, {
5586
- flushAt: 1,
5587
- flushInterval: 1
5588
- });
5589
- this.send("started");
5590
- }
5591
- }
5592
- login(sub, user) {
5593
- if (!this.posthog) {
5594
- return;
5595
- }
5596
- const alias = this.distinctId;
5597
- this.distinctId = sub;
5598
- this.posthog.alias({ distinctId: this.distinctId, alias });
5599
- this.posthog.identify({
5600
- distinctId: this.distinctId,
5601
- properties: {
5602
- email: user.email_address,
5603
- sub,
5604
- teamCount: user.teams.length
5605
- }
5606
- });
5607
- this.send("logged in");
5608
- }
5609
- send(event, properties = {}) {
5610
- var _a;
5611
- (_a = this.posthog) == null ? void 0 : _a.capture({
5612
- distinctId: this.distinctId,
5613
- event: [this.prefix, event].join(" "),
5614
- properties: {
5615
- version: package_default.version,
5616
- ...properties
5617
- }
5618
- });
5619
- }
5620
- shutdown() {
5621
- var _a;
5622
- this.send("exited", { exitCode: process.exitCode });
5623
- return (_a = this.posthog) == null ? void 0 : _a.shutdownAsync();
5624
- }
5625
- };
5626
-
5627
5657
  // src/commands/new/index.ts
5628
5658
  var stableApiHost = "https://uniform.app";
5629
5659
  var apiHostDefault = process.env.UNIFORM_CLI_BASE_URL || stableApiHost;