create-newt-app 0.31.4 → 0.31.5

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.d.ts CHANGED
@@ -23,6 +23,7 @@ type Options = {
23
23
  nestDiOnly: boolean;
24
24
  includeExample: boolean;
25
25
  extras: readonly Extra[];
26
+ explicitFlags: readonly string[];
26
27
  };
27
28
  declare function doInit(options: Options): Promise<void>;
28
29
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/templates/types.ts","../src/index.ts"],"mappings":";KAgCY;;;cCdN;cACA;cACA;cACA;KAGD,kBAAkB;KAClB,mBAAmB;KACnB,iBAAiB;KACjB,qBAAqB;KAcrB;EACH;EACA;EACA;EACA;EACA;EACA,SAAS;EACT,UAAU;EACV,QAAQ;EACR,YAAY;EACZ;EACA;EACA,iBAAiB;;iBAWG,OAAO,SAAS,UAAO"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/templates/types.ts","../src/index.ts"],"mappings":";KAgCY;;;cCbN;cACA;cACA;cACA;KAGD,kBAAkB;KAClB,mBAAmB;KACnB,iBAAiB;KACjB,qBAAqB;KAcrB;EACH;EACA;EACA;EACA;EACA;EACA,SAAS;EACT,UAAU;EACV,QAAQ;EACR,YAAY;EACZ;EACA;EACA,iBAAiB;EACjB;;iBAWoB,OAAO,SAAS,UAAO"}
package/dist/index.js CHANGED
@@ -9,8 +9,12 @@ import { execa } from "execa";
9
9
  import ejs from "ejs";
10
10
  import { existsSync, promises } from "fs";
11
11
  import path from "path";
12
+ import { homedir } from "node:os";
13
+ import { promises as promises$1 } from "node:fs";
14
+ import https from "node:https";
15
+ import path$1 from "node:path";
12
16
  //#region package.json
13
- var version = "0.31.4";
17
+ var version = "0.31.5";
14
18
  var engines = { "node": ">=24.0.0" };
15
19
  //#endregion
16
20
  //#region src/templates/root/index.ts
@@ -12582,6 +12586,135 @@ async function initGit(cwd) {
12582
12586
  ], { cwd });
12583
12587
  }
12584
12588
  //#endregion
12589
+ //#region src/telemetry.ts
12590
+ const ENDPOINT = "https://newt-telemetry.newt-app.workers.dev";
12591
+ const SEND_TIMEOUT_MS = 2e3;
12592
+ const UNREACHABLE_BACKOFF_MS = 2592e6;
12593
+ const CI_PROVIDERS = [
12594
+ ["GITHUB_ACTIONS", "github-actions"],
12595
+ ["GITLAB_CI", "gitlab-ci"],
12596
+ ["CIRCLECI", "circleci"],
12597
+ ["TRAVIS", "travis"],
12598
+ ["BUILDKITE", "buildkite"],
12599
+ ["JENKINS_URL", "jenkins"],
12600
+ ["TEAMCITY_VERSION", "teamcity"],
12601
+ ["CODEBUILD_BUILD_ID", "codebuild"],
12602
+ ["VERCEL", "vercel"],
12603
+ ["NETLIFY", "netlify"]
12604
+ ];
12605
+ function detectCi(env = process.env) {
12606
+ const named = CI_PROVIDERS.find(([key]) => env[key]);
12607
+ if (named) return named[1];
12608
+ return env.CI ? "unknown" : "none";
12609
+ }
12610
+ function isOptedOut(env = process.env) {
12611
+ if (env.DO_NOT_TRACK === "1" || env.DO_NOT_TRACK?.toLowerCase() === "true") return true;
12612
+ if (env.NEWT_TELEMETRY_DISABLED === "1") return true;
12613
+ if (env.NEWT_TELEMETRY !== void 0) return env.NEWT_TELEMETRY !== "1";
12614
+ return false;
12615
+ }
12616
+ function isEnabled(env = process.env) {
12617
+ return Boolean(ENDPOINT) && !isOptedOut(env);
12618
+ }
12619
+ function statePath() {
12620
+ const base = process.env.XDG_STATE_HOME ?? path$1.join(homedir(), ".local", "state");
12621
+ return path$1.join(base, "create-newt-app", "telemetry.json");
12622
+ }
12623
+ async function readState() {
12624
+ try {
12625
+ return JSON.parse(await promises$1.readFile(statePath(), "utf8"));
12626
+ } catch {
12627
+ return {};
12628
+ }
12629
+ }
12630
+ async function writeState(next) {
12631
+ try {
12632
+ const file = statePath();
12633
+ await promises$1.mkdir(path$1.dirname(file), { recursive: true });
12634
+ await promises$1.writeFile(file, JSON.stringify(next), "utf8");
12635
+ } catch {}
12636
+ }
12637
+ function nodeMajor(version = process.version) {
12638
+ const match = /^v?(\d+)/.exec(version);
12639
+ return match ? `v${match[1]}` : "other";
12640
+ }
12641
+ function buildPayload(report) {
12642
+ const { selection } = report;
12643
+ return {
12644
+ cliVersion: version,
12645
+ nodeMajor: nodeMajor(),
12646
+ platform: process.platform,
12647
+ mode: report.mode,
12648
+ ci: detectCi(),
12649
+ explicitFlags: [...report.explicitFlags].sort().join(","),
12650
+ shadcn: selection.shadcn,
12651
+ testing: selection.testing,
12652
+ database: selection.database,
12653
+ linter: selection.linter,
12654
+ deployment: selection.deployment,
12655
+ nestDiOnly: selection.nestDiOnly,
12656
+ todoExample: selection.todoExample,
12657
+ antiSlop: selection.extras.includes("anti-slop")
12658
+ };
12659
+ }
12660
+ function post(body) {
12661
+ return new Promise((resolve) => {
12662
+ try {
12663
+ const req = https.request(ENDPOINT, {
12664
+ method: "POST",
12665
+ headers: {
12666
+ "content-type": "application/json",
12667
+ "content-length": Buffer.byteLength(body)
12668
+ },
12669
+ timeout: SEND_TIMEOUT_MS
12670
+ });
12671
+ req.on("response", (res) => {
12672
+ res.resume();
12673
+ const status = res.statusCode ?? 0;
12674
+ res.on("end", () => resolve(status >= 200 && status < 300));
12675
+ });
12676
+ req.on("timeout", () => {
12677
+ req.destroy();
12678
+ resolve(false);
12679
+ });
12680
+ req.on("error", () => resolve(false));
12681
+ req.end(body);
12682
+ } catch {
12683
+ resolve(false);
12684
+ }
12685
+ });
12686
+ }
12687
+ const NOTICE = [
12688
+ "create-newt-app sends one anonymous event per scaffold: the options you chose,",
12689
+ "the CLI and Node major versions, your platform, whether prompts or flags were",
12690
+ "used, and whether this is CI. No project name, no paths, no file contents, and",
12691
+ "no identifier of any kind.",
12692
+ "Opt out with DO_NOT_TRACK=1 or NEWT_TELEMETRY_DISABLED=1."
12693
+ ].join("\n");
12694
+ async function reportRun(report) {
12695
+ if (!isEnabled()) return;
12696
+ const state = await readState();
12697
+ if (state.unreachableUntil && state.unreachableUntil > Date.now()) return;
12698
+ if (!state.notifiedAt) {
12699
+ console.log();
12700
+ console.log(NOTICE);
12701
+ console.log();
12702
+ await writeState({
12703
+ ...state,
12704
+ notifiedAt: Date.now()
12705
+ });
12706
+ }
12707
+ if (!await post(JSON.stringify(buildPayload(report)))) await writeState({
12708
+ ...state,
12709
+ notifiedAt: state.notifiedAt ?? Date.now(),
12710
+ unreachableUntil: Date.now() + UNREACHABLE_BACKOFF_MS
12711
+ });
12712
+ else if (state.unreachableUntil) await writeState({
12713
+ ...state,
12714
+ unreachableUntil: void 0
12715
+ });
12716
+ }
12717
+ //#endregion
12585
12718
  //#region src/index.ts
12586
12719
  const TESTING_CHOICES = ["jest", "vitest"];
12587
12720
  const DATABASE_CHOICES = ["sqlite", "postgres"];
@@ -12766,6 +12899,12 @@ async function doInit(options) {
12766
12899
  console.log(chalk.blue(` cd ${name}`));
12767
12900
  console.log(chalk.blue(` pnpm dev`));
12768
12901
  console.log();
12902
+ await reportRun({
12903
+ mode: options.nonInteractive ? "flags" : "interactive",
12904
+ explicitFlags: options.explicitFlags,
12905
+ selection
12906
+ });
12907
+ process.exit(0);
12769
12908
  } catch (error) {
12770
12909
  console.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
12771
12910
  process.exit(1);
@@ -12774,16 +12913,17 @@ async function doInit(options) {
12774
12913
  const program = new Command();
12775
12914
  program.name("create-newt-app").version(version).description("Create a new newt-app monorepo").argument("[name]").option("-ni, --no-install", "Skip pnpm install", true).option("-ng, --no-git", "Skip git initialization", true).option("--shadcn", "Include shadcn/ui", false).option("--testing <framework>", "Testing framework: vitest or jest", "jest").option("--database <database>", "Database: sqlite or postgres", "sqlite").option("--linter <linter>", "Linter: eslint or oxc", "eslint").option("--deployment <strategy>", "Deployment: none, standalone, or spa", "none").option("--nest-di-only", "Use NestJS for dependency injection only", false).option("--include-example", "Include the todo example", false).option("--extras <list>", "Extras, comma-separated: anti-slop", "").action(async (name, options, command) => {
12776
12915
  intro(`Create a ${chalk.blue("newt")} app.`);
12777
- const nonInteractive = [
12778
- "shadcn",
12779
- "testing",
12780
- "database",
12781
- "linter",
12782
- "deployment",
12783
- "nestDiOnly",
12784
- "includeExample",
12785
- "extras"
12786
- ].some((flag) => command.getOptionValueSource(flag) === "cli");
12916
+ const explicitFlags = Object.entries({
12917
+ shadcn: "--shadcn",
12918
+ testing: "--testing",
12919
+ database: "--database",
12920
+ linter: "--linter",
12921
+ deployment: "--deployment",
12922
+ nestDiOnly: "--nest-di-only",
12923
+ includeExample: "--include-example",
12924
+ extras: "--extras"
12925
+ }).filter(([option]) => command.getOptionValueSource(option) === "cli").map(([, flag]) => flag);
12926
+ const nonInteractive = explicitFlags.length > 0;
12787
12927
  const extras = options.extras.split(",").map((extra) => extra.trim()).filter(Boolean);
12788
12928
  const invalid = [
12789
12929
  {
@@ -12828,7 +12968,8 @@ program.name("create-newt-app").version(version).description("Create a new newt-
12828
12968
  deployment: options.deployment,
12829
12969
  nestDiOnly: options.nestDiOnly,
12830
12970
  includeExample: options.includeExample,
12831
- extras
12971
+ extras,
12972
+ explicitFlags
12832
12973
  });
12833
12974
  });
12834
12975
  program.parse();