@prismicio/cli 0.0.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 (84) hide show
  1. package/bin/prismic.js +47 -0
  2. package/dist/_node_modules/meow/build/dependencies.js +9040 -0
  3. package/dist/_node_modules/meow/build/dependencies.js.map +1 -0
  4. package/dist/_node_modules/meow/build/index.js +80 -0
  5. package/dist/_node_modules/meow/build/index.js.map +1 -0
  6. package/dist/_node_modules/meow/build/options.js +86 -0
  7. package/dist/_node_modules/meow/build/options.js.map +1 -0
  8. package/dist/_node_modules/meow/build/parser.js +61 -0
  9. package/dist/_node_modules/meow/build/parser.js.map +1 -0
  10. package/dist/_node_modules/meow/build/utils.js +8 -0
  11. package/dist/_node_modules/meow/build/utils.js.map +1 -0
  12. package/dist/_node_modules/meow/build/validate.js +102 -0
  13. package/dist/_node_modules/meow/build/validate.js.map +1 -0
  14. package/dist/cli.d.ts +12 -0
  15. package/dist/cli.js +147 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/commands/init.d.ts +7 -0
  18. package/dist/commands/init.js +34 -0
  19. package/dist/commands/init.js.map +1 -0
  20. package/dist/commands/sync.d.ts +6 -0
  21. package/dist/commands/sync.js +32 -0
  22. package/dist/commands/sync.js.map +1 -0
  23. package/dist/core/auth.d.ts +2 -0
  24. package/dist/core/auth.js +72 -0
  25. package/dist/core/auth.js.map +1 -0
  26. package/dist/core/customType.d.ts +6 -0
  27. package/dist/core/customType.js +43 -0
  28. package/dist/core/customType.js.map +1 -0
  29. package/dist/core/framework.d.ts +41 -0
  30. package/dist/core/framework.js +128 -0
  31. package/dist/core/framework.js.map +1 -0
  32. package/dist/core/project.d.ts +19 -0
  33. package/dist/core/project.js +92 -0
  34. package/dist/core/project.js.map +1 -0
  35. package/dist/core/repository.d.ts +6 -0
  36. package/dist/core/repository.js +33 -0
  37. package/dist/core/repository.js.map +1 -0
  38. package/dist/core/slices.d.ts +6 -0
  39. package/dist/core/slices.js +47 -0
  40. package/dist/core/slices.js.map +1 -0
  41. package/dist/core/version.d.ts +15 -0
  42. package/dist/core/version.js +27 -0
  43. package/dist/core/version.js.map +1 -0
  44. package/dist/index.d.ts +1 -0
  45. package/dist/index.js +5 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/packages/cli/package.json.js +63 -0
  48. package/dist/packages/cli/package.json.js.map +1 -0
  49. package/dist/utils/error.d.ts +8 -0
  50. package/dist/utils/error.js +18 -0
  51. package/dist/utils/error.js.map +1 -0
  52. package/dist/utils/listr.d.ts +5 -0
  53. package/dist/utils/listr.js +12 -0
  54. package/dist/utils/listr.js.map +1 -0
  55. package/dist/utils/output.d.ts +3 -0
  56. package/dist/utils/output.js +34 -0
  57. package/dist/utils/output.js.map +1 -0
  58. package/dist/utils/package.d.ts +10 -0
  59. package/dist/utils/package.js +20 -0
  60. package/dist/utils/package.js.map +1 -0
  61. package/dist/utils/sentry.d.ts +10 -0
  62. package/dist/utils/sentry.js +62 -0
  63. package/dist/utils/sentry.js.map +1 -0
  64. package/dist/utils/telemetry.d.ts +14 -0
  65. package/dist/utils/telemetry.js +42 -0
  66. package/dist/utils/telemetry.js.map +1 -0
  67. package/package.json +84 -0
  68. package/src/cli.ts +186 -0
  69. package/src/commands/init.ts +68 -0
  70. package/src/commands/sync.ts +58 -0
  71. package/src/core/auth.ts +98 -0
  72. package/src/core/customType.ts +64 -0
  73. package/src/core/framework.ts +180 -0
  74. package/src/core/project.ts +148 -0
  75. package/src/core/repository.ts +51 -0
  76. package/src/core/slices.ts +67 -0
  77. package/src/core/version.ts +50 -0
  78. package/src/index.ts +1 -0
  79. package/src/utils/error.ts +40 -0
  80. package/src/utils/listr.ts +13 -0
  81. package/src/utils/output.ts +45 -0
  82. package/src/utils/package.ts +29 -0
  83. package/src/utils/sentry.ts +104 -0
  84. package/src/utils/telemetry.ts +70 -0
@@ -0,0 +1,148 @@
1
+ import type {
2
+ PackageManager,
3
+ PrismicConfig,
4
+ PrismicManager,
5
+ } from "@prismicio/manager";
6
+ import chalk from "chalk";
7
+
8
+ import { type Framework, detectFramework } from "../core/framework";
9
+ import { listr, listrRun } from "../utils/listr";
10
+ import { updateSentryContext } from "../utils/sentry";
11
+
12
+ type DetectProjectStateArgs = {
13
+ manager: PrismicManager;
14
+ commandType: "init" | "sync";
15
+ };
16
+
17
+ export async function detectProjectState(
18
+ args: DetectProjectStateArgs,
19
+ ): Promise<void> {
20
+ const { manager, commandType } = args;
21
+
22
+ let prismicConfig: PrismicConfig | undefined;
23
+
24
+ try {
25
+ prismicConfig = await manager.project.getPrismicConfig();
26
+ } catch {
27
+ // We want to manage the error depending on the need to be initialized or not
28
+ }
29
+
30
+ const legacyConfigExists = await manager.project.checkLegacyConfigExists();
31
+
32
+ if (commandType === "init" && (prismicConfig || legacyConfigExists)) {
33
+ throw new Error("Project has already been initialized.");
34
+ } else if (commandType === "sync" && !prismicConfig) {
35
+ if (legacyConfigExists) {
36
+ await manager.project.migrateLegacyConfig();
37
+ } else {
38
+ throw new Error("Project requires initialization before syncing.");
39
+ }
40
+ }
41
+ }
42
+
43
+ export type ProjectContext = {
44
+ framework: Framework;
45
+ packageManager: PackageManager;
46
+ };
47
+
48
+ export async function detectProjectContext(
49
+ manager: PrismicManager,
50
+ ): Promise<ProjectContext> {
51
+ let framework: Framework | undefined;
52
+ let packageManager: PackageManager | undefined;
53
+
54
+ await listrRun([
55
+ {
56
+ title: "Detecting environment...",
57
+ task: (_, parentTask) =>
58
+ listr([
59
+ {
60
+ title: "Detecting framework...",
61
+ task: async (_, task) => {
62
+ framework = await detectFramework(manager.cwd);
63
+
64
+ // Update Sentry context for the framework
65
+ updateSentryContext({ framework: framework.telemetryID });
66
+
67
+ task.title = `Detected framework ${chalk.cyan(framework.name)}`;
68
+ },
69
+ },
70
+ {
71
+ title: "Detecting package manager...",
72
+ task: async (_, task) => {
73
+ packageManager = await manager.project.detectPackageManager({
74
+ root: manager.cwd,
75
+ });
76
+
77
+ task.title = `Detected package manager ${chalk.cyan(
78
+ packageManager,
79
+ )}`;
80
+
81
+ if (!framework) {
82
+ throw new Error(
83
+ "Project framework must be available through context to proceed",
84
+ );
85
+ }
86
+
87
+ parentTask.title = `Detected framework ${chalk.cyan(
88
+ framework.name,
89
+ )} and package manager ${chalk.cyan(packageManager)}`;
90
+ },
91
+ },
92
+ ]),
93
+ },
94
+ ]);
95
+
96
+ if (!framework) {
97
+ throw new Error(
98
+ "Project framework must be available through context to proceed",
99
+ );
100
+ }
101
+
102
+ if (!packageManager) {
103
+ throw new Error(
104
+ "Project package manager must be available through context to proceed",
105
+ );
106
+ }
107
+
108
+ return {
109
+ framework,
110
+ packageManager,
111
+ };
112
+ }
113
+
114
+ type CreatePrismicConfigArgs = {
115
+ manager: PrismicManager;
116
+ projectContext: ProjectContext;
117
+ repositoryName: string;
118
+ };
119
+
120
+ export async function createPrismicConfig(
121
+ args: CreatePrismicConfigArgs,
122
+ ): Promise<void> {
123
+ const { manager, projectContext, repositoryName } = args;
124
+ const { framework } = projectContext;
125
+
126
+ return listrRun([
127
+ {
128
+ title: "Creating Prismic configuration...",
129
+ task: async (_, parentTask) => {
130
+ parentTask.title = "Creating Prismic configuration...";
131
+
132
+ const prismicConfigPath =
133
+ await manager.project.suggestPrismicConfigPath();
134
+
135
+ await manager.project.writePrismicConfig({
136
+ config: {
137
+ repositoryName,
138
+ adapter: framework.adapterName,
139
+ libraries: ["./slices"],
140
+ },
141
+ path: prismicConfigPath,
142
+ });
143
+
144
+ parentTask.title = "Created Prismic configuration";
145
+ },
146
+ },
147
+ ]);
148
+ }
@@ -0,0 +1,51 @@
1
+ import type { PrismicManager } from "@prismicio/manager";
2
+
3
+ import { listrRun } from "../utils/listr";
4
+ import { updateSentryContext } from "../utils/sentry";
5
+
6
+ export type ValidateRepositoryArgs = {
7
+ manager: PrismicManager;
8
+ repository: string;
9
+ };
10
+
11
+ export async function validateRepository(
12
+ args: ValidateRepositoryArgs,
13
+ ): Promise<void> {
14
+ const { manager, repository } = args;
15
+
16
+ return listrRun([
17
+ {
18
+ title: `Validating repository...`,
19
+ task: async (_, task) => {
20
+ // Update Sentry context for the repository name
21
+ updateSentryContext({ repositoryName: repository });
22
+
23
+ const repositoryExists = await manager.prismicRepository.checkExists({
24
+ domain: repository,
25
+ });
26
+ if (!repositoryExists) {
27
+ throw new Error(`Repository ${repository} does not exist.`);
28
+ }
29
+
30
+ const userRepositories = await manager.prismicRepository.readAll();
31
+ const userSelectedRepository = userRepositories.find(
32
+ (repo) => repo.domain === repository,
33
+ );
34
+ if (!userSelectedRepository) {
35
+ throw new Error(`You're not part of the repository ${repository}.`);
36
+ }
37
+
38
+ const hasWriteAccess = await manager.prismicRepository.hasWriteAccess(
39
+ userSelectedRepository,
40
+ );
41
+ if (!hasWriteAccess) {
42
+ throw new Error(
43
+ `You do not have administrator access to repository ${repository}.`,
44
+ );
45
+ }
46
+
47
+ task.title = `Validated repository (${repository})`;
48
+ },
49
+ },
50
+ ]);
51
+ }
@@ -0,0 +1,67 @@
1
+ import type { PrismicManager } from "@prismicio/manager";
2
+
3
+ import { listrRun } from "../utils/listr";
4
+
5
+ type SaveSlicesArgs = {
6
+ manager: PrismicManager;
7
+ };
8
+
9
+ export async function saveSlices(args: SaveSlicesArgs): Promise<void> {
10
+ const { manager } = args;
11
+
12
+ // Save slices to local directory
13
+ await listrRun([
14
+ {
15
+ title: "Fetching Prismic slices...",
16
+ task: async (_, parentTask) => {
17
+ const slices = await manager.slices.fetchRemoteSlices();
18
+
19
+ parentTask.title = "Saving Prismic slices changes...";
20
+
21
+ const localSlices = await manager.slices.readAllSlices();
22
+
23
+ // Handle slices update
24
+ for (const remoteSlice of slices) {
25
+ const localSlice = localSlices.models.find(
26
+ (local) => local.model.id === remoteSlice.id,
27
+ );
28
+ if (localSlice) {
29
+ await manager.slices.updateSlice({
30
+ libraryID: localSlice.libraryID,
31
+ model: remoteSlice,
32
+ });
33
+ }
34
+ }
35
+
36
+ // Handle slices deletion
37
+ for (const localSlice of localSlices.models) {
38
+ const existsRemotely = slices.some(
39
+ (slice) => slice.id === localSlice.model.id,
40
+ );
41
+ if (!existsRemotely) {
42
+ await manager.slices.deleteSlice({
43
+ libraryID: localSlice.libraryID,
44
+ sliceID: localSlice.model.id,
45
+ });
46
+ }
47
+ }
48
+
49
+ // Handle slices creation
50
+ const defaultLibraryID = await manager.slices.getDefaultLibraryID();
51
+ for (const remoteSlice of slices) {
52
+ const existsLocally = localSlices.models.some(
53
+ (localSlice) => localSlice.model.id === remoteSlice.id,
54
+ );
55
+ if (!existsLocally) {
56
+ await manager.slices.createSlice({
57
+ libraryID: defaultLibraryID,
58
+ model: remoteSlice,
59
+ });
60
+ }
61
+ }
62
+
63
+ parentTask.title = "Prismic slices changes saved";
64
+ },
65
+ },
66
+ ]);
67
+ }
@@ -0,0 +1,50 @@
1
+ import type { PrismicManager } from "@prismicio/manager";
2
+ import semver from "semver";
3
+
4
+ import { listrRun } from "../utils/listr";
5
+
6
+ type CheckCLIVersionArgs = {
7
+ manager: PrismicManager;
8
+ currentVersion: string;
9
+ };
10
+
11
+ /**
12
+ * Checks if the current CLI version is the latest available version. Throws an
13
+ * Error if the version is outdated.
14
+ *
15
+ * @param args - Arguments object containing the manager and current version.
16
+ *
17
+ * @throws Error If the current version is not the latest.
18
+ */
19
+ export async function checkCLIVersion(
20
+ args: CheckCLIVersionArgs,
21
+ ): Promise<void> {
22
+ await listrRun([
23
+ {
24
+ title: "Checking CLI version...",
25
+ task: async (_, parentTask) => {
26
+ // Skip version check if current version is a pre-release (alpha, beta, rc, etc.)
27
+ if (semver.prerelease(args.currentVersion) !== null) {
28
+ parentTask.title =
29
+ "CLI version is a pre-release, skipping version check";
30
+ } else {
31
+ const isLatestVersion =
32
+ await args.manager.versions.checkIsCLIVersionLatest({
33
+ currentVersion: args.currentVersion,
34
+ });
35
+
36
+ if (!isLatestVersion) {
37
+ const latestVersion =
38
+ await args.manager.versions.getLatestCLIVersion();
39
+
40
+ throw new Error(
41
+ `You are using an outdated version (${args.currentVersion}). The latest version is ${latestVersion}.`,
42
+ );
43
+ }
44
+
45
+ parentTask.title = "CLI version is up to date";
46
+ }
47
+ },
48
+ },
49
+ ]);
50
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { run } from "./cli";
@@ -0,0 +1,40 @@
1
+ import semver from "semver";
2
+
3
+ import * as pkg from "../../package.json";
4
+
5
+ /**
6
+ * Checks if we should show errors in the console. Errors are shown in
7
+ * development mode or when using a pre-release version.
8
+ *
9
+ * @returns Whether to show errors.
10
+ */
11
+ const shouldShowErrors = (): boolean => {
12
+ // Show errors in development mode
13
+ if (import.meta.env.DEV) {
14
+ return true;
15
+ }
16
+
17
+ // Show errors if it's a pre-release version
18
+ if (semver.prerelease(pkg.version) !== null) {
19
+ return true;
20
+ }
21
+
22
+ return false;
23
+ };
24
+
25
+ /**
26
+ * Handles errors that should not break the CLI by logging them in
27
+ * dev/pre-release mode, or silently failing otherwise.
28
+ *
29
+ * @param error - The error that occurred.
30
+ * @param context - Context about what operation failed.
31
+ */
32
+ export function handleSilentError(error: unknown, context: string): void {
33
+ if (shouldShowErrors()) {
34
+ const errorMessage = error instanceof Error ? error.message : String(error);
35
+ console.error(
36
+ `[${context}] Failed: ${errorMessage}`,
37
+ error instanceof Error ? error : undefined,
38
+ );
39
+ }
40
+ }
@@ -0,0 +1,13 @@
1
+ import { Listr, type ListrTask, type ListrOptions } from "listr2";
2
+
3
+ type ListrArgs = [tasks: ListrTask[], options?: ListrOptions];
4
+
5
+ export const listr = (...[tasks, options]: ListrArgs): Listr => {
6
+ return new Listr(tasks, options);
7
+ };
8
+
9
+ export const listrRun = async (
10
+ ...[tasks, options]: ListrArgs
11
+ ): Promise<void> => {
12
+ return listr(tasks, options).run();
13
+ };
@@ -0,0 +1,45 @@
1
+ import chalk from "chalk";
2
+
3
+ import { version as pkgVersion } from "../../package.json";
4
+
5
+ export function displayHeader(): void {
6
+ console.info(
7
+ chalk.cyan.bold("┌" + "─".repeat(48) + "┐\n") +
8
+ chalk.white(" Prismic ") +
9
+ chalk.gray(`v${pkgVersion}\n`) +
10
+ chalk.cyan.bold("└" + "─".repeat(48) + "┘\n"),
11
+ );
12
+ }
13
+
14
+ export function displaySuccess(message: string, context?: string): void {
15
+ console.info("\n" + chalk.green.bold("✓ Success"));
16
+ console.info(chalk.green("─".repeat(50)));
17
+ console.info(chalk.green(message));
18
+ if (context) {
19
+ console.info(chalk.gray(context + "\n"));
20
+ } else {
21
+ console.info();
22
+ }
23
+ }
24
+
25
+ export function displayError(error: unknown): void {
26
+ const errorMessage = error instanceof Error ? error.message : String(error);
27
+ const errorStack =
28
+ error instanceof Error && error.stack ? error.stack : undefined;
29
+
30
+ console.error("\n" + chalk.red.bold("✕ Error"));
31
+ console.error(chalk.red("─".repeat(50)));
32
+ console.error(chalk.red(errorMessage) + "\n");
33
+
34
+ if (errorStack) {
35
+ console.error(chalk.gray("Stack trace:"));
36
+ console.error(chalk.gray(errorStack) + "\n");
37
+ }
38
+
39
+ console.error(
40
+ chalk.gray("─".repeat(50)) +
41
+ chalk.gray("\nNeed help?") +
42
+ chalk.white("\n • Documentation: https://prismic.io/docs") +
43
+ chalk.white("\n • Raise an issue: https://community.prismic.io\n"),
44
+ );
45
+ }
@@ -0,0 +1,29 @@
1
+ import semver from "semver";
2
+
3
+ type PackageManifest = { name: string; version: string };
4
+ type PackageInfo = { environment: string; release: string };
5
+
6
+ export function getPackageInfo(pkg: PackageManifest): PackageInfo {
7
+ const parsedPkgVersion = semver.parse(pkg.version);
8
+ if (parsedPkgVersion === null) {
9
+ throw new Error(
10
+ `Package \`${pkg.name}\` has an invalid version \`${pkg.version}\` in its manifest.`,
11
+ );
12
+ }
13
+
14
+ let environment;
15
+ if (parsedPkgVersion.prerelease.length === 0) {
16
+ environment = import.meta.env.MODE || "production";
17
+ } else if (
18
+ parsedPkgVersion.prerelease[0] === "alpha" ||
19
+ parsedPkgVersion.prerelease[0] === "beta"
20
+ ) {
21
+ environment = parsedPkgVersion.prerelease[0];
22
+ } else {
23
+ throw new Error(
24
+ `Invalid package version: \`${pkg.name}@${parsedPkgVersion.version}\`. The first prerelease component \`${parsedPkgVersion.prerelease[0]}\` must be either \`alpha\` or \`beta\`.`,
25
+ );
26
+ }
27
+
28
+ return { environment, release: parsedPkgVersion.version };
29
+ }
@@ -0,0 +1,104 @@
1
+ import { PrismicUserProfile } from "@prismicio/manager";
2
+ import * as Sentry from "@sentry/node";
3
+
4
+ import * as pkg from "../../package.json";
5
+
6
+ import { handleSilentError } from "./error";
7
+ import { getPackageInfo } from "./package";
8
+
9
+ const SENTRY_DSN =
10
+ import.meta.env.VITE_SENTRY_DSN ||
11
+ "https://e1886b1775bd397cd1afc60bfd2ebfc8@o146123.ingest.us.sentry.io/4510445143588864";
12
+
13
+ /**
14
+ * Checks whether or not Sentry is enabled.
15
+ *
16
+ * Sentry is enabled automatically in production but can be disabled by setting
17
+ * `VITE_ENABLE_SENTRY` to `false`.
18
+ *
19
+ * @returns Whether or not Sentry is enabled.
20
+ */
21
+ const checkIsSentryEnabled = (): boolean =>
22
+ import.meta.env.VITE_ENABLE_SENTRY === undefined
23
+ ? import.meta.env.PROD
24
+ : import.meta.env.VITE_ENABLE_SENTRY === "true";
25
+
26
+ export async function trackSentryError(error: unknown): Promise<void> {
27
+ try {
28
+ if (!checkIsSentryEnabled()) {
29
+ return;
30
+ }
31
+
32
+ Sentry.captureException(error, {
33
+ ...(error instanceof Error
34
+ ? { extra: { cause: error.cause, fullCommand: process.argv.join(" ") } }
35
+ : {}),
36
+ });
37
+
38
+ // Flush Sentry events before process exit
39
+ await Sentry.flush();
40
+ } catch (sentryError) {
41
+ handleSilentError(sentryError, "Sentry tracking error");
42
+ }
43
+ }
44
+
45
+ export function setupSentry(): void {
46
+ try {
47
+ if (!checkIsSentryEnabled()) {
48
+ return;
49
+ }
50
+
51
+ const { environment, release } = getPackageInfo(pkg);
52
+
53
+ Sentry.init({
54
+ dsn: SENTRY_DSN,
55
+ release,
56
+ environment,
57
+ // Increase the default truncation length of 250 to 2500 (x10)
58
+ // to have enough details in Sentry
59
+ maxValueLength: 2_500,
60
+ });
61
+ } catch (error) {
62
+ handleSilentError(error, "Sentry setup error");
63
+ }
64
+ }
65
+
66
+ type UpdateSentryContextArgs = {
67
+ repositoryName?: string;
68
+ framework?: string;
69
+ userProfile?: PrismicUserProfile;
70
+ };
71
+
72
+ export async function updateSentryContext({
73
+ repositoryName,
74
+ framework,
75
+ userProfile,
76
+ }: UpdateSentryContextArgs): Promise<void> {
77
+ try {
78
+ if (!checkIsSentryEnabled()) {
79
+ return;
80
+ }
81
+
82
+ if (userProfile) {
83
+ Sentry.setUser({ id: userProfile.shortId });
84
+ }
85
+
86
+ if (repositoryName) {
87
+ Sentry.setTag("repository", repositoryName);
88
+ Sentry.setContext("Repository Data", {
89
+ name: repositoryName,
90
+ });
91
+ }
92
+
93
+ if (framework) {
94
+ Sentry.setTag("framework", framework);
95
+ }
96
+
97
+ Sentry.setContext("Process", {
98
+ "Command used": process.argv.join(" "),
99
+ cwd: process.cwd(),
100
+ });
101
+ } catch (error) {
102
+ handleSilentError(error, "Sentry context update error");
103
+ }
104
+ }
@@ -0,0 +1,70 @@
1
+ import type { PrismicManager } from "@prismicio/manager";
2
+
3
+ import { name as pkgName, version as pkgVersion } from "../../package.json";
4
+
5
+ import { handleSilentError } from "./error";
6
+
7
+ type InitTelemetryArgs = {
8
+ manager: PrismicManager;
9
+ commandType: "init" | "sync";
10
+ repositoryName?: string;
11
+ };
12
+
13
+ export async function initTelemetry(args: InitTelemetryArgs): Promise<void> {
14
+ const { manager, commandType, repositoryName } = args;
15
+
16
+ await manager.telemetry.initTelemetry({
17
+ appName: pkgName,
18
+ appVersion: pkgVersion,
19
+ });
20
+
21
+ // Get repository name from project config if not provided
22
+ let resolvedRepositoryName = repositoryName;
23
+ if (!resolvedRepositoryName) {
24
+ resolvedRepositoryName = await manager.project.getRepositoryName();
25
+ }
26
+
27
+ await manager.telemetry.track({
28
+ event: "prismic-cli:start",
29
+ repository: resolvedRepositoryName,
30
+ commandType,
31
+ fullCommand: process.argv.join(" "),
32
+ });
33
+ }
34
+
35
+ type TrackErrorTelemetryArgs = {
36
+ manager: PrismicManager;
37
+ error: unknown;
38
+ commandType: "init" | "sync";
39
+ };
40
+
41
+ export async function trackErrorTelemetry(
42
+ args: TrackErrorTelemetryArgs,
43
+ ): Promise<void> {
44
+ const { manager, error, commandType } = args;
45
+
46
+ // Transform error to string and prevent hitting Segment 500kb API limit
47
+ const safeError = (error instanceof Error ? error.message : `${error}`).slice(
48
+ 0,
49
+ 512,
50
+ );
51
+
52
+ let repositoryName;
53
+ try {
54
+ repositoryName = await manager.project.getRepositoryName();
55
+ } catch (error) {
56
+ handleSilentError(
57
+ error,
58
+ "Telemetry track error while getting repository name",
59
+ );
60
+ }
61
+
62
+ await manager.telemetry.track({
63
+ event: "prismic-cli:end",
64
+ commandType,
65
+ repository: repositoryName,
66
+ fullCommand: process.argv.join(" "),
67
+ success: false,
68
+ error: safeError,
69
+ });
70
+ }