@slicemachine/init 1.1.1-alpha.2 → 1.1.1-alpha.20

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/build/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  const core = require('@slicemachine/core');
6
6
  const ServerAnalytics = require('analytics-node');
7
+ const uuid = require('uuid');
7
8
  const path = require('path');
8
9
  const util = require('util');
9
10
  const child_process = require('child_process');
@@ -11,7 +12,6 @@ const inquirer = require('inquirer');
11
12
  const Separator = require('inquirer/lib/objects/separator');
12
13
  const cookie = require('@slicemachine/core/build/src/utils/cookie');
13
14
  const axios = require('axios');
14
- const t = require('io-ts');
15
15
  const _function = require('fp-ts/function');
16
16
  const Either = require('fp-ts/Either');
17
17
  const tmp = require('tmp');
@@ -48,44 +48,109 @@ const util__default = /*#__PURE__*/_interopDefaultLegacy(util);
48
48
  const inquirer__namespace = /*#__PURE__*/_interopNamespace(inquirer);
49
49
  const Separator__default = /*#__PURE__*/_interopDefaultLegacy(Separator);
50
50
  const axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
51
- const t__namespace = /*#__PURE__*/_interopNamespace(t);
52
51
  const tmp__default = /*#__PURE__*/_interopDefaultLegacy(tmp);
53
52
  const AdmZip__default = /*#__PURE__*/_interopDefaultLegacy(AdmZip);
54
53
  const fsExtra__default = /*#__PURE__*/_interopDefaultLegacy(fsExtra);
55
54
  const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
56
55
  const Files__default = /*#__PURE__*/_interopDefaultLegacy(Files);
57
56
 
58
- class Tracker {
59
- constructor(analytics, repo, identifier, tracking = true) {
60
- this.analytics = analytics;
61
- this.repo = repo;
62
- this.identifier = identifier;
63
- this.tracking = tracking;
64
- this.Track = {
65
- downloadLibrary: (library) => {
66
- this.trackEvent("SliceMachine Download Library" /* DownloadLibrary */, { library });
67
- }
68
- };
57
+ var __accessCheck = (obj, member, msg) => {
58
+ if (!member.has(obj))
59
+ throw TypeError("Cannot " + msg);
60
+ };
61
+ var __privateGet = (obj, member, getter) => {
62
+ __accessCheck(obj, member, "read from private field");
63
+ return getter ? getter.call(obj) : member.get(obj);
64
+ };
65
+ var __privateAdd = (obj, member, value) => {
66
+ if (member.has(obj))
67
+ throw TypeError("Cannot add the same private member more than once");
68
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
69
+ };
70
+ var __privateSet = (obj, member, value, setter) => {
71
+ __accessCheck(obj, member, "write to private field");
72
+ setter ? setter.call(obj, value) : member.set(obj, value);
73
+ return value;
74
+ };
75
+ var _client, _isTrackingActive, _anonymousId, _userId;
76
+ class InitTracker {
77
+ constructor() {
78
+ __privateAdd(this, _client, null);
79
+ __privateAdd(this, _isTrackingActive, true);
80
+ __privateAdd(this, _anonymousId, "");
81
+ __privateAdd(this, _userId, null);
69
82
  }
70
- static build(writeKey, repo, identifier, tracking = true) {
83
+ initialize(segmentKey, isTrackingActive = true) {
71
84
  try {
72
- if (!repo)
85
+ if (!!__privateGet(this, _client))
73
86
  return;
74
- const analytics = new ServerAnalytics__default["default"](writeKey);
75
- return new Tracker(analytics, repo, identifier, tracking);
87
+ __privateSet(this, _isTrackingActive, isTrackingActive);
88
+ __privateSet(this, _anonymousId, uuid.v4());
89
+ __privateSet(this, _client, new ServerAnalytics__default["default"](segmentKey));
76
90
  } catch (error) {
77
- console.warn(error);
91
+ }
92
+ }
93
+ _trackEvent(eventType, attributes = {}) {
94
+ if (!this._isTrackingPossible(__privateGet(this, _client))) {
78
95
  return;
79
96
  }
97
+ const identifier = this._createSegmentIdentifier();
98
+ try {
99
+ __privateGet(this, _client).track({
100
+ event: eventType,
101
+ ...identifier,
102
+ properties: attributes
103
+ });
104
+ } catch (e) {
105
+ }
80
106
  }
81
- trackEvent(eventType, attributes = {}) {
82
- this.tracking && this.analytics.track({
83
- event: eventType,
84
- ...this.identifier,
85
- properties: attributes
86
- });
107
+ _identifyEvent(userId) {
108
+ if (!this._isTrackingPossible(__privateGet(this, _client))) {
109
+ return;
110
+ }
111
+ try {
112
+ __privateGet(this, _client).identify({
113
+ userId,
114
+ anonymousId: __privateGet(this, _anonymousId)
115
+ });
116
+ } catch (e) {
117
+ }
118
+ }
119
+ _isTrackingPossible(client) {
120
+ return !!client && __privateGet(this, _isTrackingActive);
121
+ }
122
+ _createSegmentIdentifier() {
123
+ return !!__privateGet(this, _userId) ? { userId: __privateGet(this, _userId) } : { anonymousId: __privateGet(this, _anonymousId) };
124
+ }
125
+ identifyUser(userId) {
126
+ __privateSet(this, _userId, userId);
127
+ this._identifyEvent(userId);
128
+ }
129
+ trackDownloadLibrary(library) {
130
+ this._trackEvent("SliceMachine Download Library" /* DownloadLibrary */, { library });
131
+ }
132
+ trackInitStart() {
133
+ this._trackEvent("SliceMachine Init Start" /* InitStart */);
134
+ }
135
+ trackInitDone(framework, repo) {
136
+ this._trackEvent("SliceMachine Init Done" /* InitDone */, { framework, repo });
87
137
  }
88
138
  }
139
+ _client = new WeakMap();
140
+ _isTrackingActive = new WeakMap();
141
+ _anonymousId = new WeakMap();
142
+ _userId = new WeakMap();
143
+ const Tracker = (() => {
144
+ let smTrackerInstance;
145
+ const init = () => new InitTracker();
146
+ return {
147
+ get() {
148
+ if (!smTrackerInstance)
149
+ smTrackerInstance = init();
150
+ return smTrackerInstance;
151
+ }
152
+ };
153
+ })();
89
154
 
90
155
  function findArgument(args, name) {
91
156
  const flagIndex = args.indexOf(`--${name}`);
@@ -133,7 +198,7 @@ async function installRequiredDependencies(cwd, framework) {
133
198
  const yarnLock = core.Utils.Files.exists(core.FileSystem.YarnLockPath(cwd));
134
199
  const installDevDependencyCommand = yarnLock ? "yarn add -D" : "npm install --save-dev";
135
200
  const installDependencyCommand = yarnLock ? "yarn add" : "npm install --save";
136
- const spinner = core.Utils.spinner("Downloading Prismic Visual Builder");
201
+ const spinner = core.Utils.spinner("Downloading Slice Machine");
137
202
  spinner.start();
138
203
  const { stderr } = await execCommand(`${installDevDependencyCommand} ${SM_PACKAGE_NAME}`);
139
204
  const deps = depsForFramework(framework);
@@ -142,7 +207,7 @@ async function installRequiredDependencies(cwd, framework) {
142
207
  const pathToPkg = path__default["default"].join(core.FileSystem.PackagePaths(cwd).value(), SM_PACKAGE_NAME);
143
208
  const isPackageInstalled = core.Utils.Files.exists(pathToPkg);
144
209
  if (isPackageInstalled || !stderr.length) {
145
- spinner.succeed("The Prismic Visual Builder was installed successfully");
210
+ spinner.succeed("Slice Machine was installed successfully");
146
211
  return;
147
212
  }
148
213
  spinner.fail();
@@ -188,7 +253,7 @@ function makeReposPretty(base) {
188
253
  return function({ name, domain, role }) {
189
254
  const address = new URL(base);
190
255
  address.hostname = `${domain}.${address.hostname}`;
191
- if (core.Utils.roles.canUpdateCustomTypes(role) === false) {
256
+ if (core.Models.canUpdateCustomTypes(role) === false) {
192
257
  return {
193
258
  name: `${core.Utils.purple.dim("Use")} ${core.Utils.bold.dim(name)} ${core.Utils.purple.dim(`"${address.hostname}"`)}`,
194
259
  value: domain,
@@ -239,7 +304,7 @@ async function maybeExistingRepo(cookies, cwd, base = DEFAULT_BASE) {
239
304
  const repos = await core.Communication.listRepositories(token);
240
305
  if (repos.length === 0) {
241
306
  const name = await promptForRepoName(base);
242
- return { existing: false, name };
307
+ return { existing: false, repository: name };
243
308
  }
244
309
  const choices = sortReposForPrompt(repos, base, cwd);
245
310
  const numberOfDisabledRepos = choices.filter((repo) => {
@@ -260,9 +325,9 @@ async function maybeExistingRepo(cookies, cwd, base = DEFAULT_BASE) {
260
325
  ]);
261
326
  if (res.repoName === CREATE_REPO) {
262
327
  const name = await promptForRepoName(base);
263
- return { existing: false, name };
328
+ return { existing: false, repository: name };
264
329
  }
265
- return { existing: true, name: res.repoName };
330
+ return { existing: true, repository: res.repoName };
266
331
  }
267
332
 
268
333
  function createRepository(domain, framework, config) {
@@ -279,7 +344,7 @@ function createRepository(domain, framework, config) {
279
344
  core.Utils.writeError(error.message);
280
345
  }
281
346
  core.Utils.writeError(`We failed to create you new prismic repository`);
282
- console.log(`Run ${core.Utils.bold("npx slicemachine init")} again!`);
347
+ console.log(`Run ${core.Utils.bold("npx @slicemachine/init")} again!`);
283
348
  process.exit(-1);
284
349
  });
285
350
  }
@@ -307,7 +372,7 @@ async function promptForFramework() {
307
372
  });
308
373
  }
309
374
  async function detectFramework(cwd) {
310
- const failMessage = `Please run ${core.Utils.bold("npx slicemachine init")} in a Nuxt or Next.js project`;
375
+ const failMessage = `Please run ${core.Utils.bold("npx @slicemachine/init")} in a Nuxt or Next.js project`;
311
376
  const spinner = core.Utils.spinner("Detecting framework to install correct dependencies");
312
377
  spinner.start();
313
378
  try {
@@ -342,24 +407,17 @@ async function detectFramework(cwd) {
342
407
  }
343
408
  }
344
409
 
345
- const UserProfile = t__namespace.exact(t__namespace.type({
346
- userId: t__namespace.string,
347
- shortId: t__namespace.string,
348
- email: t__namespace.string,
349
- firstName: t__namespace.string,
350
- lastName: t__namespace.string
351
- }));
352
410
  async function getUserProfile(cookies, base = core.Utils.CONSTS.DEFAULT_BASE) {
353
- const url = new URL(base);
354
- url.hostname = `user.${url.hostname}`;
411
+ const userServiceBase = core.Utils.CONSTS.DEFAULT_BASE === base ? core.Utils.CONSTS.USER_SERVICE_BASE : "https://user.wroom.io/";
412
+ const url = new URL(userServiceBase);
355
413
  url.pathname = "profile";
356
414
  const endpoint = url.toString();
357
415
  const token = core.Utils.Cookie.parsePrismicAuthToken(cookies);
358
416
  return axios__default["default"].get(endpoint, {
359
417
  headers: {
360
- Authorization: `Bearer Token ${token}`
418
+ Authorization: `Bearer ${token}`
361
419
  }
362
- }).then((res) => _function.pipe(UserProfile.decode(res.data), Either.fold(() => {
420
+ }).then((res) => _function.pipe(core.Models.UserProfile.decode(res.data), Either.fold(() => {
363
421
  throw new Error("Can't parse user profile");
364
422
  }, (data) => data)));
365
423
  }
@@ -418,7 +476,7 @@ function configureProject(cwd, base, repository, framework, sliceLibPath = [], t
418
476
  core.FileSystem.addJsonPackageSmScript(cwd);
419
477
  spinner.succeed("Project configured! Ready to start");
420
478
  } catch (e) {
421
- spinner.fail("Failed to configure your Prismic Local Builder");
479
+ spinner.fail("Failed to configure Slice Machine");
422
480
  process.exit(-1);
423
481
  }
424
482
  }
@@ -426,7 +484,7 @@ function configureProject(cwd, base, repository, framework, sliceLibPath = [], t
426
484
  function displayFinalMessage(cwd) {
427
485
  const yarnLock = core.Utils.Files.exists(core.FileSystem.YarnLockPath(cwd));
428
486
  const command = `${yarnLock ? "yarn" : "npm"} run ${core.Utils.CONSTS.SCRIPT_NAME}`;
429
- console.log(`${core.Utils.white("\u25A0")} Run ${core.Utils.purple(command)} to now launch your Local Builder`);
487
+ console.log(`${core.Utils.white("\u25A0")} Run ${core.Utils.purple(command)} to now launch Slice Machine`);
430
488
  }
431
489
 
432
490
  const Dependencies = {
@@ -487,7 +545,7 @@ const downloadFile = async (reqUrl) => {
487
545
  function toGithubSource(githubPath, branch) {
488
546
  return `https://codeload.github.com/${githubPath}/zip/${branch}`;
489
547
  }
490
- async function installLib(tracker, cwd, libGithubPath, branch = "HEAD") {
548
+ async function installLib(cwd, libGithubPath, branch = "HEAD") {
491
549
  const spinner = core.Utils.spinner(`Installing the ${libGithubPath} lib in your project...`);
492
550
  try {
493
551
  spinner.start();
@@ -522,7 +580,7 @@ async function installLib(tracker, cwd, libGithubPath, branch = "HEAD") {
522
580
  return `~/${name}/${path2.replace("src/", "")}`;
523
581
  });
524
582
  spinner.succeed(`Slice library "${libGithubPath}" was installed successfully`);
525
- tracker == null ? void 0 : tracker.Track.downloadLibrary(libGithubPath);
583
+ Tracker.get().trackDownloadLibrary(libGithubPath);
526
584
  return localLibs;
527
585
  } catch (error) {
528
586
  spinner.fail(`Error installing ${libGithubPath} lib!`);
@@ -534,29 +592,31 @@ async function installLib(tracker, cwd, libGithubPath, branch = "HEAD") {
534
592
  }
535
593
 
536
594
  async function init() {
537
- var _a;
538
595
  const cwd = findArgument(process.argv, "cwd") || process.cwd();
539
596
  const base = findArgument(process.argv, "base") || core.Utils.CONSTS.DEFAULT_BASE;
540
597
  const lib = findArgument(process.argv, "library");
541
598
  const branch = findArgument(process.argv, "branch");
542
- const isTrackingAvailable = findArgument(process.argv, "tracking") === "false" ? false : true;
599
+ const isTrackingAvailable = findArgument(process.argv, "tracking") !== "false";
600
+ Tracker.get().initialize("JfTfmHaATChc4xueS7RcCBsixI71dJIJ" , isTrackingAvailable);
601
+ Tracker.get().trackInitStart();
543
602
  console.log(core.Utils.purple("You're about to configure Slicemachine... Press ctrl + C to cancel"));
544
603
  validatePkg(cwd);
545
604
  const user = await loginOrBypass(base);
546
605
  if (!user)
547
606
  throw new Error("The user should be logged in!");
607
+ if (user.profile) {
608
+ Tracker.get().identifyUser(user.profile.shortId);
609
+ }
548
610
  const config = core.FileSystem.PrismicSharedConfigManager.get();
549
611
  const frameworkResult = await detectFramework(cwd);
550
- const { existing, name } = await maybeExistingRepo(config.cookies, cwd, config.base);
612
+ const { existing, repository } = await maybeExistingRepo(config.cookies, cwd, config.base);
551
613
  if (!existing) {
552
- await createRepository(name, frameworkResult.value, config);
614
+ await createRepository(repository, frameworkResult.value, config);
553
615
  }
554
- const tracker = ((_a = user.profile) == null ? void 0 : _a.shortId) ? Tracker.build("JfTfmHaATChc4xueS7RcCBsixI71dJIJ" , name, {
555
- userId: user.profile.shortId
556
- }, isTrackingAvailable) : void 0;
557
616
  await installRequiredDependencies(cwd, frameworkResult.value);
558
- const sliceLibPath = lib ? await installLib(tracker, cwd, lib, branch) : void 0;
559
- configureProject(cwd, base, name, frameworkResult, sliceLibPath, isTrackingAvailable);
617
+ const sliceLibPath = lib ? await installLib(cwd, lib, branch) : void 0;
618
+ configureProject(cwd, base, repository, frameworkResult, sliceLibPath, isTrackingAvailable);
619
+ Tracker.get().trackInitDone(frameworkResult.value, repository);
560
620
  displayFinalMessage(cwd);
561
621
  }
562
622
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils/tracker.ts","../src/utils/index.ts","../src/steps/install-required-dependencies.ts","../src/steps/validate-pkg.ts","../src/steps/maybe-existing-repo.ts","../src/steps/create-repo.ts","../src/steps/detect-framework.ts","../src/utils/communication.ts","../src/steps/loginOrBypass.ts","../src/steps/configure-project.ts","../src/steps/display-final-message.ts","../src/utils/PackageManager.ts","../src/steps/install-lib.ts","../src/index.ts"],"sourcesContent":["/*\n * DUPLICATION\n * this file is a duplication of ServerTracker in sm-ui\n * this duplication has been done on purpose to simplify the merge if init becomes part of sm-ui\n * or if we decide to share the tracker implementation from a lib, but it'll need some refactoring\n * Duplication means no entanglement so don't merge this with the other implem and keep the structure.\n */\n\nimport ServerAnalytics from \"analytics-node\";\n\nexport enum EventType {\n DownloadLibrary = \"SliceMachine Download Library\",\n}\n\nexport class Tracker {\n constructor(\n readonly analytics: ServerAnalytics,\n readonly repo: string,\n readonly identifier: { userId: string } | { anonymousId: string },\n readonly tracking = true\n ) {}\n\n static build(\n writeKey: string,\n repo: string | undefined,\n identifier: { userId: string } | { anonymousId: string },\n tracking = true\n ): Tracker | undefined {\n try {\n if (!repo) return;\n const analytics = new ServerAnalytics(writeKey);\n return new Tracker(analytics, repo, identifier, tracking);\n } catch (error) {\n console.warn(error);\n return;\n }\n }\n\n private trackEvent(\n eventType: EventType,\n attributes: Record<string, unknown> = {}\n ): void {\n this.tracking &&\n this.analytics.track({\n event: eventType,\n ...this.identifier,\n properties: attributes,\n });\n }\n\n Track = {\n // not called, for demo only\n downloadLibrary: (library: string): void => {\n this.trackEvent(EventType.DownloadLibrary, { library });\n },\n };\n}\n","import util from \"util\";\nimport { exec } from \"child_process\";\n\nexport function findArgument(args: string[], name: string): string | undefined {\n const flagIndex: number = args.indexOf(`--${name}`);\n\n if (flagIndex === -1) return;\n if (args.length < flagIndex + 2) return;\n\n const flagValue = args[flagIndex + 1];\n\n if (flagValue.startsWith(\"--\")) return;\n return flagValue;\n}\n\nexport const execCommand: (\n command: string\n) => Promise<{ stderr: string; stdout: string }> = util.promisify(exec);\n","import path from \"path\";\nimport { execCommand } from \"../utils\";\nimport { Utils, FileSystem, Models } from \"@slicemachine/core\";\n\nconst {\n PRISMIC_CLIENT,\n PRISMIC_DOM_PACKAGE_NAME,\n PRISMIC_REACT_PACKAGE_NAME,\n NEXT_SLICEZONE,\n SM_PACKAGE_NAME,\n NUXT_PRISMIC,\n NUXT_SM,\n VUE_SLICEZONE,\n PRISMIC_VUE,\n SLICE_SIMULATOR_REACT,\n SLICE_SIMULATOR_VUE,\n} = Utils.CONSTS;\n\nfunction depsForFramework(framework: Models.Frameworks): string {\n switch (framework) {\n case Models.Frameworks.react:\n return `${PRISMIC_REACT_PACKAGE_NAME} ${PRISMIC_CLIENT}`;\n case Models.Frameworks.next:\n return `${PRISMIC_REACT_PACKAGE_NAME} ${PRISMIC_CLIENT}@v5.1.1 ${NEXT_SLICEZONE} ${SLICE_SIMULATOR_REACT}`;\n case Models.Frameworks.svelte:\n return `${PRISMIC_DOM_PACKAGE_NAME} ${PRISMIC_CLIENT}`;\n case Models.Frameworks.nuxt:\n return `${NUXT_PRISMIC} ${NUXT_SM} ${VUE_SLICEZONE} ${SLICE_SIMULATOR_VUE}`;\n case Models.Frameworks.vue:\n return `${PRISMIC_VUE} ${PRISMIC_CLIENT}@v5.1.1 ${PRISMIC_DOM_PACKAGE_NAME} ${VUE_SLICEZONE}`;\n default:\n return \"\";\n }\n}\n\nexport async function installRequiredDependencies(\n cwd: string,\n framework: Models.Frameworks\n): Promise<void> {\n const yarnLock = Utils.Files.exists(FileSystem.YarnLockPath(cwd));\n const installDevDependencyCommand = yarnLock\n ? \"yarn add -D\"\n : \"npm install --save-dev\";\n const installDependencyCommand = yarnLock ? \"yarn add\" : \"npm install --save\";\n\n const spinner = Utils.spinner(\"Downloading Prismic Visual Builder\");\n spinner.start();\n\n const { stderr } = await execCommand(\n `${installDevDependencyCommand} ${SM_PACKAGE_NAME}`\n );\n\n const deps = depsForFramework(framework);\n if (deps) await execCommand(`${installDependencyCommand} ${deps}`);\n\n const pathToPkg = path.join(\n FileSystem.PackagePaths(cwd).value(),\n SM_PACKAGE_NAME\n );\n const isPackageInstalled = Utils.Files.exists(pathToPkg);\n\n if (isPackageInstalled || !stderr.length) {\n spinner.succeed(\"The Prismic Visual Builder was installed successfully\");\n return;\n }\n\n spinner.fail();\n Utils.writeWarning(\n `could not install ${SM_PACKAGE_NAME}. Please do it manually!`\n );\n}\n","import { FileSystem, Utils } from \"@slicemachine/core\";\n\nexport function validatePkg(cwd: string): void {\n const jsonPackage = FileSystem.retrieveJsonPackage(cwd);\n if (!jsonPackage.exists) {\n Utils.writeError(`package.json not found. Are you in the right folder?`);\n return process.exit(-1);\n }\n if (!jsonPackage.content) {\n Utils.writeError(`could not parse package.json.`);\n return process.exit(-1);\n }\n}\n","import * as inquirer from \"inquirer\";\nimport Separator from \"inquirer/lib/objects/separator\";\nimport { Communication, Utils, FileSystem } from \"@slicemachine/core\";\nimport { Repositories } from \"@slicemachine/core/src/models/Repositories\";\nimport { Repository } from \"@slicemachine/core/src/models/Repository\";\nimport { parsePrismicAuthToken } from \"@slicemachine/core/build/src/utils/cookie\";\n\nexport const CREATE_REPO = \"$_CREATE_REPO\"; // not a valid domain name\nconst DEFAULT_BASE = Utils.CONSTS.DEFAULT_BASE;\n\nexport function prettyRepoName(address: URL, value?: string): string {\n const repoName = value ? Utils.cyan(value) : Utils.dim.cyan(\"repo-name\");\n return `${Utils.cyan.dim(`${address.protocol}//`)}${repoName}${Utils.cyan.dim(\n `.${address.hostname}`\n )}`;\n}\n\nexport async function promptForRepoName(base: string): Promise<string> {\n const address = new URL(base);\n\n Utils.writeInfo(\n \"The name acts as a domain/endpoint for your content repo and should be completely unique.\"\n );\n\n return inquirer\n .prompt<Record<string, string>>([\n {\n name: \"repoName\",\n message: \"Name your Prismic repository\",\n type: \"input\",\n required: true,\n transformer: (value) => prettyRepoName(address, String(value)),\n async validate(name: string) {\n const result = await Communication.validateRepositoryName(\n name,\n base,\n false\n );\n return result === name || result;\n },\n },\n ])\n .then((res) => res.repoName);\n}\n\nexport type RepoPrompt = { name: string; value: string; disabled?: string };\n\nexport type PromptOrSeparator = RepoPrompt | Separator;\n\nexport type RepoPrompts = Array<PromptOrSeparator>;\n\nexport function makeReposPretty(base: string) {\n return function ({ name, domain, role }: Repository): RepoPrompt {\n const address = new URL(base);\n address.hostname = `${domain}.${address.hostname}`;\n if (Utils.roles.canUpdateCustomTypes(role) === false) {\n return {\n name: `${Utils.purple.dim(\"Use\")} ${Utils.bold.dim(\n name\n )} ${Utils.purple.dim(`\"${address.hostname}\"`)}`,\n value: domain,\n disabled: \"Unauthorized\",\n };\n }\n\n return {\n name: `${Utils.purple(\"Use\")} ${Utils.bold(name)} ${Utils.purple(\n `\"${address.hostname}\"`\n )}`,\n value: name,\n };\n };\n}\n\nexport function orderPrompts(maybeName?: string | null) {\n return (a: PromptOrSeparator, b: PromptOrSeparator): number => {\n if (a instanceof Separator || b instanceof Separator) return 0;\n if (maybeName && (a.value === maybeName || b.value === maybeName)) return 0;\n if (a.value === CREATE_REPO || b.value === CREATE_REPO) return 0;\n if (a.disabled && !b.disabled) return 1;\n if (!a.disabled && b.disabled) return -1;\n return 0;\n };\n}\n\nexport function maybeStickTheRepoToTheTopOfTheList(repoName?: string | null) {\n return (acc: RepoPrompts, curr: RepoPrompt): RepoPrompts => {\n if (repoName && curr.value === repoName) {\n return [curr, ...acc];\n }\n return [...acc, curr];\n };\n}\n\nexport function sortReposForPrompt(\n repos: Repositories,\n base: string,\n cwd: string\n): RepoPrompts {\n const createNew = {\n name: `${Utils.purple(\"Create a\")} ${Utils.bold(\"new\")} ${Utils.purple(\n \"Repository\"\n )}`,\n value: CREATE_REPO,\n };\n\n const maybeConfiguredRepoName = FileSystem.maybeRepoNameFromSMFile(cwd, base);\n\n return repos\n .reverse()\n .map(makeReposPretty(base))\n .reduce(maybeStickTheRepoToTheTopOfTheList(maybeConfiguredRepoName), [\n createNew,\n ])\n .sort(orderPrompts(maybeConfiguredRepoName));\n}\n\nexport async function maybeExistingRepo(\n cookies: string,\n cwd: string,\n base = DEFAULT_BASE\n): Promise<{ name: string; existing: boolean }> {\n const token = parsePrismicAuthToken(cookies);\n const repos = await Communication.listRepositories(token);\n\n if (repos.length === 0) {\n const name = await promptForRepoName(base);\n return { existing: false, name };\n }\n\n const choices = sortReposForPrompt(repos, base, cwd);\n\n const numberOfDisabledRepos = choices.filter((repo) => {\n if (repo instanceof Separator) return false;\n return repo.disabled;\n }).length;\n\n const res = await inquirer.prompt<Record<string, string>>([\n {\n type: \"list\",\n name: \"repoName\",\n default: 0,\n required: true,\n message: \"Connect a Prismic Repository or create a new one\",\n choices,\n pageSize: numberOfDisabledRepos + 2 <= 7 ? 7 : numberOfDisabledRepos + 2,\n // loop: false\n },\n ]);\n\n if (res.repoName === CREATE_REPO) {\n const name = await promptForRepoName(base);\n return { existing: false, name };\n }\n return { existing: true, name: res.repoName };\n}\n","import { Communication, Utils } from \"@slicemachine/core\";\nimport type { Models } from \"@slicemachine/core\";\n\nexport function createRepository(\n domain: string,\n framework: Models.Frameworks,\n config: Models.PrismicSharedConfig\n): Promise<void> {\n const spinner = Utils.spinner(\"Creating Prismic Repository\");\n spinner.start();\n\n return Communication.createRepository(\n domain,\n config.cookies,\n framework,\n config.base\n )\n .then((res) => {\n const addressUrl = new URL(config.base);\n addressUrl.hostname = `${res.data.domain || domain}.${\n addressUrl.hostname\n }`;\n const address = addressUrl.toString();\n spinner.succeed(`We created your new repository ${address}`);\n })\n .catch((error: Error) => {\n spinner.fail(`Error creating repository ${domain}`);\n if (error.message) {\n Utils.writeError(error.message);\n }\n Utils.writeError(`We failed to create you new prismic repository`);\n console.log(`Run ${Utils.bold(\"npx slicemachine init\")} again!`);\n process.exit(-1);\n });\n}\n","import { Utils } from \"@slicemachine/core\";\nimport { Models } from \"@slicemachine/core\";\nimport * as inquirer from \"inquirer\";\n\nexport type FrameworkResult = {\n value: Models.Frameworks;\n manuallyAdded: boolean;\n};\n\nexport async function promptForFramework(): Promise<FrameworkResult> {\n const choices = Models.SupportedFrameworks.map((framework) => {\n return {\n name: Utils.Framework.fancyName(framework),\n value: framework,\n };\n });\n\n return inquirer\n .prompt<{ framework: Models.Frameworks }>([\n {\n name: \"framework\",\n type: \"list\",\n message: \"Select a framework to use\",\n required: true,\n choices,\n },\n ])\n .then((res) => {\n return {\n value: res.framework,\n manuallyAdded: true,\n };\n });\n}\n\nexport async function detectFramework(cwd: string): Promise<FrameworkResult> {\n const failMessage = `Please run ${Utils.bold(\n \"npx slicemachine init\"\n )} in a Nuxt or Next.js project`;\n\n const spinner = Utils.spinner(\n \"Detecting framework to install correct dependencies\"\n );\n\n spinner.start();\n\n try {\n const maybeFramework = Utils.Framework.defineFramework({\n cwd,\n supportedFrameworks: Object.values(Models.Frameworks),\n });\n\n spinner.stop();\n\n if (!maybeFramework || maybeFramework === Models.Frameworks.vanillajs) {\n Utils.writeError(\"Framework not detected\");\n return await promptForFramework();\n }\n\n const nameToPrint = Utils.Framework.fancyName(maybeFramework);\n\n if (!Utils.Framework.isFrameworkSupported(maybeFramework)) {\n Utils.writeError(`${nameToPrint} is currently not supported`);\n console.log(failMessage);\n process.exit(1);\n }\n\n Utils.writeCheck(`${nameToPrint} detected`);\n\n return {\n value: maybeFramework,\n manuallyAdded: false,\n };\n } catch (error) {\n spinner.fail(\"package.json not found\");\n\n if (error instanceof Error && error.message) {\n Utils.writeError(error.message);\n } else {\n console.log(failMessage);\n }\n\n process.exit(1);\n }\n}\n","import axios from \"axios\";\nimport * as t from \"io-ts\";\nimport { pipe } from \"fp-ts/function\";\nimport { fold } from \"fp-ts/Either\";\nimport { Utils, Communication, FileSystem } from \"@slicemachine/core\";\n\nconst UserProfile = t.exact(\n t.type({\n userId: t.string,\n shortId: t.string,\n email: t.string,\n firstName: t.string,\n lastName: t.string,\n })\n);\n\nexport type UserProfile = t.TypeOf<typeof UserProfile>;\n\nexport async function getUserProfile(\n cookies: string,\n base = Utils.CONSTS.DEFAULT_BASE\n): Promise<UserProfile> {\n // note the auth server also provides a userId\n\n const url = new URL(base);\n url.hostname = `user.${url.hostname}`;\n url.pathname = \"profile\";\n\n const endpoint = url.toString();\n const token = Utils.Cookie.parsePrismicAuthToken(cookies);\n\n return axios\n .get<UserProfile>(endpoint, {\n headers: {\n Authorization: `Bearer Token ${token}`,\n },\n })\n .then((res) =>\n pipe(\n UserProfile.decode(res.data),\n fold<t.Errors, UserProfile, UserProfile>(\n () => {\n throw new Error(\"Can't parse user profile\");\n },\n (data: UserProfile) => data\n )\n )\n );\n}\n\nexport async function validateSessionAndGetProfile(\n base = Utils.CONSTS.DEFAULT_BASE\n): Promise<{\n info: Communication.UserInfo;\n profile: UserProfile | null;\n} | null> {\n const config = FileSystem.PrismicSharedConfigManager.get();\n\n if (!config.cookies.length) return Promise.resolve(null); // default config, logged out.\n if (base != config.base) return Promise.resolve(null); // not the same base so it doesn't\n\n try {\n const info = await Communication.validateSession(config.cookies, base);\n const profile = await getUserProfile(config.cookies, base).catch(\n () => null\n );\n if (profile?.shortId) {\n FileSystem.PrismicSharedConfigManager.setProperties({\n shortId: profile.shortId,\n });\n }\n return { info, profile };\n } catch {\n return null;\n }\n}\n","import { Utils, Communication, Auth } from \"@slicemachine/core\";\nimport {\n validateSessionAndGetProfile,\n UserProfile,\n} from \"../utils/communication\";\n\nexport async function loginOrBypass(base: string): Promise<{\n info: Communication.UserInfo;\n profile: UserProfile | null;\n} | null> {\n const user = await validateSessionAndGetProfile(base).catch((err) =>\n console.log(err)\n );\n if (user) {\n const email = user.info.email;\n Utils.writeCheck(`Logged in as ${Utils.bold(email)}`);\n return user;\n } else {\n await Auth.login(base);\n const user = await validateSessionAndGetProfile(base);\n return user;\n }\n}\n","import { FileSystem, Utils } from \"@slicemachine/core\";\nimport type { Models } from \"@slicemachine/core\";\nimport { FrameworkResult } from \"./detect-framework\";\n\ntype Base = Utils.Endpoints.Base;\n\nexport function configureProject(\n cwd: string,\n base: Base,\n repository: string,\n framework: FrameworkResult,\n sliceLibPath: string[] = [],\n tracking = true\n): void {\n const spinner = Utils.spinner(\n `Configuring your ${framework.value} & Prismic project...`\n );\n spinner.start();\n\n try {\n const manifest = FileSystem.retrieveManifest(cwd);\n\n const manifestUpdated: Models.Manifest = {\n ...(manifest.exists && manifest.content ? manifest.content : {}),\n apiEndpoint: Utils.Endpoints.buildRepositoryEndpoint(base, repository),\n libraries: [\"@/slices\", ...sliceLibPath],\n ...(framework.manuallyAdded ? { framework: framework.value } : {}),\n ...(!tracking ? { tracking } : {}),\n };\n\n if (!manifest.exists) FileSystem.createManifest(cwd, manifestUpdated);\n else FileSystem.patchManifest(cwd, manifestUpdated);\n\n // create the default slices folder if it doesn't exist.\n const pathToSlicesFolder = FileSystem.CustomPaths(cwd)\n .library(\"slices\")\n .value();\n if (!Utils.Files.exists(pathToSlicesFolder))\n Utils.Files.mkdir(pathToSlicesFolder, { recursive: true });\n\n // add slicemachine script to package.json.\n FileSystem.addJsonPackageSmScript(cwd);\n\n spinner.succeed(\"Project configured! Ready to start\");\n } catch {\n spinner.fail(\"Failed to configure your Prismic Local Builder\");\n process.exit(-1);\n }\n}\n","import { Utils, FileSystem } from \"@slicemachine/core\";\n\nexport function displayFinalMessage(cwd: string): void {\n const yarnLock = Utils.Files.exists(FileSystem.YarnLockPath(cwd));\n const command = `${yarnLock ? \"yarn\" : \"npm\"} run ${\n Utils.CONSTS.SCRIPT_NAME\n }`;\n\n console.log(\n `${Utils.white(\"■\")} Run ${Utils.purple(\n command\n )} to now launch your Local Builder`\n );\n}\n","import { Utils, FileSystem } from \"@slicemachine/core\";\nimport { execCommand } from \"../utils\";\n\nexport type Dependency = string | { name: string; version: string };\nexport const Dependencies = {\n fromPkgFormat(\n pkgDeps: Record<string, string> | undefined\n ): ReadonlyArray<Dependency> | undefined {\n if (!pkgDeps) return;\n\n return Object.entries(pkgDeps).map(([name, version]) => ({\n name,\n version,\n }));\n },\n};\nfunction formatDeps(dependencies: ReadonlyArray<Dependency>): string {\n return dependencies\n .map((dep) => {\n if (typeof dep === \"string\") return dep;\n return `${dep.name}@${dep.version}`;\n })\n .join(\" \");\n}\n\nexport interface PackageManager {\n install(dependencies: ReadonlyArray<Dependency>): Promise<{ stderr: string }>;\n installDev(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }>;\n}\n\nexport const PackageManager = {\n get(cwd: string): PackageManager {\n if (Utils.Files.exists(FileSystem.YarnLockPath(cwd))) {\n return Yarn;\n }\n return Npm;\n },\n};\n\nexport const Yarn: PackageManager = {\n install(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }> {\n return execCommand(`yarn add ${formatDeps(dependencies)}`);\n },\n installDev(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }> {\n return execCommand(`yarn add --dev ${formatDeps(dependencies)}`);\n },\n};\n\nexport const Npm: PackageManager = {\n install(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }> {\n return execCommand(`npm i --save ${formatDeps(dependencies)}`);\n },\n installDev(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }> {\n return execCommand(`npm i --save-dev ${formatDeps(dependencies)}`);\n },\n};\n","import { Utils } from \"@slicemachine/core\";\nimport tmp from \"tmp\";\nimport AdmZip from \"adm-zip\";\nimport fsExtra from \"fs-extra\";\nimport axios from \"axios\";\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { getOrElseW } from \"fp-ts/Either\";\nimport { PackageManager, Dependencies } from \"../utils/PackageManager\";\nimport { PackageJsonHelper } from \"@slicemachine/core/build/src/utils/PackageJson\";\nimport {\n Manifest,\n ManifestHelper,\n} from \"@slicemachine/core/build/src/models/Manifest\";\nimport Files from \"@slicemachine/core/build/src/utils/files\";\nimport { Tracker } from \"../utils/tracker\";\n\nconst downloadFile = async (reqUrl: string): Promise<string> => {\n const res = await axios.get<Buffer>(reqUrl, { responseType: \"arraybuffer\" });\n\n return new Promise((resolve, reject) => {\n if (res.status == 200) {\n const tmpZipFile = tmp.tmpNameSync();\n const zip = new AdmZip(res.data);\n zip.extractAllTo(tmpZipFile);\n resolve(tmpZipFile);\n } else {\n reject();\n }\n });\n};\n\nfunction toGithubSource(githubPath: string, branch: string): string {\n return `https://codeload.github.com/${githubPath}/zip/${branch}`;\n}\n\nexport async function installLib(\n tracker: Tracker | undefined,\n cwd: string,\n libGithubPath: string,\n branch = \"HEAD\"\n): Promise<string[] | undefined> {\n const spinner = Utils.spinner(\n `Installing the ${libGithubPath} lib in your project...`\n );\n\n try {\n spinner.start();\n\n const [githubUserName, githubProjectName] = libGithubPath.split(\"/\");\n const source = toGithubSource(libGithubPath, branch);\n\n const zipFilePath = await downloadFile(source);\n const outputFolder = `${githubProjectName}-${branch}`;\n const projectPath = path.join(zipFilePath, outputFolder);\n\n const name = `${githubUserName}-${githubProjectName}`;\n const libDestinationFolder = path.join(cwd, name);\n\n // We should be able to offer the ability to override or not an existing library\n if (fs.existsSync(libDestinationFolder)) {\n spinner.succeed(`Lib \"${libGithubPath}\" was already installed (skipped)`);\n return;\n }\n\n // We copy all the slices into the the user project minus the src folder\n fsExtra.moveSync(path.join(projectPath, \"src\"), libDestinationFolder);\n\n // handle dependencies\n const pkgManager = PackageManager.get(cwd);\n const pkgJson = PackageJsonHelper.fromPath(\n path.join(projectPath, \"package.json\")\n );\n if (pkgJson instanceof Error) throw pkgJson;\n\n const dependencies = Dependencies.fromPkgFormat(pkgJson.dependencies);\n if (dependencies) await pkgManager.install(dependencies);\n\n // generate meta file\n Files.write(path.join(libDestinationFolder, \"meta.json\"), {\n name: pkgJson.name,\n });\n\n // retrieve all slices lib paths\n const manifest = Files.readEntity<Error | Manifest>(\n path.join(projectPath, \"sm.json\"),\n (payload: unknown) => {\n return getOrElseW(\n () => new Error(`Unable to parse sm.json from lib ${libGithubPath}`)\n )(Manifest.decode(payload));\n }\n );\n if (manifest instanceof Error) throw manifest;\n\n const localLibs = ManifestHelper.localLibraries(manifest).map(\n ({ path }) => {\n return `~/${name}/${path.replace(\"src/\", \"\")}`;\n }\n );\n\n spinner.succeed(\n `Slice library \"${libGithubPath}\" was installed successfully`\n );\n\n tracker?.Track.downloadLibrary(libGithubPath);\n return localLibs;\n } catch (error) {\n spinner.fail(`Error installing ${libGithubPath} lib!`);\n if (error instanceof Error) {\n console.error(error.message);\n }\n process.exit(-1);\n }\n}\n","import { Utils, FileSystem } from \"@slicemachine/core\";\nimport { Tracker } from \"./utils/tracker\";\nimport {\n installRequiredDependencies,\n validatePkg,\n maybeExistingRepo,\n createRepository,\n loginOrBypass,\n configureProject,\n displayFinalMessage,\n detectFramework,\n installLib,\n} from \"./steps\";\nimport { findArgument } from \"./utils\";\n\nasync function init() {\n const cwd = findArgument(process.argv, \"cwd\") || process.cwd();\n const base = findArgument(process.argv, \"base\") || Utils.CONSTS.DEFAULT_BASE;\n const lib: string | undefined = findArgument(process.argv, \"library\");\n const branch: string | undefined = findArgument(process.argv, \"branch\");\n const isTrackingAvailable =\n findArgument(process.argv, \"tracking\") === \"false\" ? false : true;\n\n console.log(\n Utils.purple(\n \"You're about to configure Slicemachine... Press ctrl + C to cancel\"\n )\n );\n\n // verify package.json file exist\n validatePkg(cwd);\n\n // login\n const user = await loginOrBypass(base);\n if (!user) throw new Error(\"The user should be logged in!\");\n\n // retrieve tokens for api calls\n const config = FileSystem.PrismicSharedConfigManager.get();\n\n // detect the framework used by the project\n const frameworkResult = await detectFramework(cwd);\n\n // select the repository used with the project.\n const { existing, name } = await maybeExistingRepo(\n config.cookies,\n cwd,\n config.base\n );\n\n if (!existing) {\n await createRepository(name, frameworkResult.value, config);\n }\n\n const tracker = user.profile?.shortId\n ? Tracker.build(\n process.env.NEXT_PUBLIC_SEGMENT_KEY ||\n \"JfTfmHaATChc4xueS7RcCBsixI71dJIJ\",\n name,\n {\n userId: user.profile.shortId,\n },\n isTrackingAvailable\n )\n : undefined;\n\n // install the required dependencies in the project.\n await installRequiredDependencies(cwd, frameworkResult.value);\n\n const sliceLibPath = lib\n ? await installLib(tracker, cwd, lib, branch)\n : undefined;\n\n // configure the SM.json file and the json package file of the project..\n configureProject(\n cwd,\n base,\n name,\n frameworkResult,\n sliceLibPath,\n isTrackingAvailable\n );\n\n // ask the user to run slice-machine.\n displayFinalMessage(cwd);\n}\n\ntry {\n void init();\n} catch (error) {\n if (error instanceof Error) Utils.writeError(error.message);\n else console.error(error);\n}\n"],"names":["ServerAnalytics","util","exec","Utils","Models","FileSystem","path","inquirer","Communication","Separator","parsePrismicAuthToken","t","axios","pipe","fold","Auth","tmp","AdmZip","fs","PackageJsonHelper","Files","getOrElseW","Manifest","ManifestHelper"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils/tracker.ts","../src/utils/index.ts","../src/steps/install-required-dependencies.ts","../src/steps/validate-pkg.ts","../src/steps/maybe-existing-repo.ts","../src/steps/create-repo.ts","../src/steps/detect-framework.ts","../src/utils/communication.ts","../src/steps/loginOrBypass.ts","../src/steps/configure-project.ts","../src/steps/display-final-message.ts","../src/utils/PackageManager.ts","../src/steps/install-lib.ts","../src/index.ts"],"sourcesContent":["import ServerAnalytics from \"analytics-node\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { Frameworks } from \"@slicemachine/core/build/src/models\";\n\nexport enum EventType {\n DownloadLibrary = \"SliceMachine Download Library\",\n InitStart = \"SliceMachine Init Start\",\n InitDone = \"SliceMachine Init Done\",\n}\n\ntype SegmentIdentifier = { userId: string } | { anonymousId: string };\n\nexport class InitTracker {\n #client: ServerAnalytics | null = null;\n #isTrackingActive = true;\n #anonymousId = \"\";\n #userId: string | null = null;\n\n initialize(segmentKey: string, isTrackingActive = true): void {\n try {\n // The initialize method cannot be used for changing some class properties\n if (!!this.#client) return;\n\n this.#isTrackingActive = isTrackingActive;\n this.#anonymousId = uuidv4();\n this.#client = new ServerAnalytics(segmentKey);\n } catch (error) {\n // If the client is not correctly setup we are silently failing as the tracker is not a critical feature\n }\n }\n\n /** Private methods **/\n\n _trackEvent(\n eventType: EventType,\n attributes: Record<string, unknown> = {}\n ): void {\n if (!this._isTrackingPossible(this.#client)) {\n return;\n }\n\n const identifier = this._createSegmentIdentifier();\n\n try {\n this.#client.track({\n event: eventType,\n ...identifier,\n properties: attributes,\n });\n } catch {\n // If the client is not correctly setup we are silently failing as the tracker is not a critical feature\n }\n }\n\n _identifyEvent(userId: string): void {\n if (!this._isTrackingPossible(this.#client)) {\n return;\n }\n\n try {\n this.#client.identify({\n userId,\n anonymousId: this.#anonymousId,\n });\n } catch {\n // If the client is not correctly setup we are silently failing as the tracker is not a critical feature\n }\n }\n\n _isTrackingPossible(\n client: ServerAnalytics | null\n ): client is ServerAnalytics {\n return !!client && this.#isTrackingActive;\n }\n\n _createSegmentIdentifier(): SegmentIdentifier {\n return !!this.#userId\n ? { userId: this.#userId }\n : { anonymousId: this.#anonymousId };\n }\n\n /** Public methods **/\n\n identifyUser(userId: string): void {\n this.#userId = userId;\n this._identifyEvent(userId);\n }\n\n trackDownloadLibrary(library: string): void {\n this._trackEvent(EventType.DownloadLibrary, { library });\n }\n\n trackInitStart(): void {\n this._trackEvent(EventType.InitStart);\n }\n\n trackInitDone(framework: Frameworks, repo: string): void {\n this._trackEvent(EventType.InitDone, { framework, repo });\n }\n}\n\nconst Tracker = (() => {\n let smTrackerInstance: InitTracker;\n\n const init = () => new InitTracker();\n\n return {\n get() {\n if (!smTrackerInstance) smTrackerInstance = init();\n return smTrackerInstance;\n },\n };\n})();\n\nexport default Tracker;\n","import util from \"util\";\nimport { exec } from \"child_process\";\n\nexport function findArgument(args: string[], name: string): string | undefined {\n const flagIndex: number = args.indexOf(`--${name}`);\n\n if (flagIndex === -1) return;\n if (args.length < flagIndex + 2) return;\n\n const flagValue = args[flagIndex + 1];\n\n if (flagValue.startsWith(\"--\")) return;\n return flagValue;\n}\n\nexport const execCommand: (\n command: string\n) => Promise<{ stderr: string; stdout: string }> = util.promisify(exec);\n","import path from \"path\";\nimport { execCommand } from \"../utils\";\nimport { Utils, FileSystem, Models } from \"@slicemachine/core\";\n\nconst {\n PRISMIC_CLIENT,\n PRISMIC_DOM_PACKAGE_NAME,\n PRISMIC_REACT_PACKAGE_NAME,\n NEXT_SLICEZONE,\n SM_PACKAGE_NAME,\n NUXT_PRISMIC,\n NUXT_SM,\n VUE_SLICEZONE,\n PRISMIC_VUE,\n SLICE_SIMULATOR_REACT,\n SLICE_SIMULATOR_VUE,\n} = Utils.CONSTS;\n\nfunction depsForFramework(framework: Models.Frameworks): string {\n switch (framework) {\n case Models.Frameworks.react:\n return `${PRISMIC_REACT_PACKAGE_NAME} ${PRISMIC_CLIENT}`;\n case Models.Frameworks.next:\n return `${PRISMIC_REACT_PACKAGE_NAME} ${PRISMIC_CLIENT}@v5.1.1 ${NEXT_SLICEZONE} ${SLICE_SIMULATOR_REACT}`;\n case Models.Frameworks.svelte:\n return `${PRISMIC_DOM_PACKAGE_NAME} ${PRISMIC_CLIENT}`;\n case Models.Frameworks.nuxt:\n return `${NUXT_PRISMIC} ${NUXT_SM} ${VUE_SLICEZONE} ${SLICE_SIMULATOR_VUE}`;\n case Models.Frameworks.vue:\n return `${PRISMIC_VUE} ${PRISMIC_CLIENT}@v5.1.1 ${PRISMIC_DOM_PACKAGE_NAME} ${VUE_SLICEZONE}`;\n default:\n return \"\";\n }\n}\n\nexport async function installRequiredDependencies(\n cwd: string,\n framework: Models.Frameworks\n): Promise<void> {\n const yarnLock = Utils.Files.exists(FileSystem.YarnLockPath(cwd));\n const installDevDependencyCommand = yarnLock\n ? \"yarn add -D\"\n : \"npm install --save-dev\";\n const installDependencyCommand = yarnLock ? \"yarn add\" : \"npm install --save\";\n\n const spinner = Utils.spinner(\"Downloading Slice Machine\");\n spinner.start();\n\n const { stderr } = await execCommand(\n `${installDevDependencyCommand} ${SM_PACKAGE_NAME}`\n );\n\n const deps = depsForFramework(framework);\n if (deps) await execCommand(`${installDependencyCommand} ${deps}`);\n\n const pathToPkg = path.join(\n FileSystem.PackagePaths(cwd).value(),\n SM_PACKAGE_NAME\n );\n const isPackageInstalled = Utils.Files.exists(pathToPkg);\n\n if (isPackageInstalled || !stderr.length) {\n spinner.succeed(\"Slice Machine was installed successfully\");\n return;\n }\n\n spinner.fail();\n Utils.writeWarning(\n `could not install ${SM_PACKAGE_NAME}. Please do it manually!`\n );\n}\n","import { FileSystem, Utils } from \"@slicemachine/core\";\n\nexport function validatePkg(cwd: string): void {\n const jsonPackage = FileSystem.retrieveJsonPackage(cwd);\n if (!jsonPackage.exists) {\n Utils.writeError(`package.json not found. Are you in the right folder?`);\n return process.exit(-1);\n }\n if (!jsonPackage.content) {\n Utils.writeError(`could not parse package.json.`);\n return process.exit(-1);\n }\n}\n","import * as inquirer from \"inquirer\";\nimport Separator from \"inquirer/lib/objects/separator\";\nimport { Communication, Utils, FileSystem, Models } from \"@slicemachine/core\";\nimport { parsePrismicAuthToken } from \"@slicemachine/core/build/src/utils/cookie\";\n\nexport const CREATE_REPO = \"$_CREATE_REPO\"; // not a valid domain name\nconst DEFAULT_BASE = Utils.CONSTS.DEFAULT_BASE;\n\nexport function prettyRepoName(address: URL, value?: string): string {\n const repoName = value ? Utils.cyan(value) : Utils.dim.cyan(\"repo-name\");\n return `${Utils.cyan.dim(`${address.protocol}//`)}${repoName}${Utils.cyan.dim(\n `.${address.hostname}`\n )}`;\n}\n\nexport async function promptForRepoName(base: string): Promise<string> {\n const address = new URL(base);\n\n Utils.writeInfo(\n \"The name acts as a domain/endpoint for your content repo and should be completely unique.\"\n );\n\n return inquirer\n .prompt<Record<string, string>>([\n {\n name: \"repoName\",\n message: \"Name your Prismic repository\",\n type: \"input\",\n required: true,\n transformer: (value) => prettyRepoName(address, String(value)),\n async validate(name: string) {\n const result = await Communication.validateRepositoryName(\n name,\n base,\n false\n );\n return result === name || result;\n },\n },\n ])\n .then((res) => res.repoName);\n}\n\nexport type RepoPrompt = { name: string; value: string; disabled?: string };\n\nexport type PromptOrSeparator = RepoPrompt | Separator;\n\nexport type RepoPrompts = Array<PromptOrSeparator>;\n\nexport function makeReposPretty(base: string) {\n return function ({ name, domain, role }: Models.Repository): RepoPrompt {\n const address = new URL(base);\n address.hostname = `${domain}.${address.hostname}`;\n if (Models.canUpdateCustomTypes(role) === false) {\n return {\n name: `${Utils.purple.dim(\"Use\")} ${Utils.bold.dim(\n name\n )} ${Utils.purple.dim(`\"${address.hostname}\"`)}`,\n value: domain,\n disabled: \"Unauthorized\",\n };\n }\n\n return {\n name: `${Utils.purple(\"Use\")} ${Utils.bold(name)} ${Utils.purple(\n `\"${address.hostname}\"`\n )}`,\n value: name,\n };\n };\n}\n\nexport function orderPrompts(maybeName?: string | null) {\n return (a: PromptOrSeparator, b: PromptOrSeparator): number => {\n if (a instanceof Separator || b instanceof Separator) return 0;\n if (maybeName && (a.value === maybeName || b.value === maybeName)) return 0;\n if (a.value === CREATE_REPO || b.value === CREATE_REPO) return 0;\n if (a.disabled && !b.disabled) return 1;\n if (!a.disabled && b.disabled) return -1;\n return 0;\n };\n}\n\nexport function maybeStickTheRepoToTheTopOfTheList(repoName?: string | null) {\n return (acc: RepoPrompts, curr: RepoPrompt): RepoPrompts => {\n if (repoName && curr.value === repoName) {\n return [curr, ...acc];\n }\n return [...acc, curr];\n };\n}\n\nexport function sortReposForPrompt(\n repos: Models.Repositories,\n base: string,\n cwd: string\n): RepoPrompts {\n const createNew = {\n name: `${Utils.purple(\"Create a\")} ${Utils.bold(\"new\")} ${Utils.purple(\n \"Repository\"\n )}`,\n value: CREATE_REPO,\n };\n\n const maybeConfiguredRepoName = FileSystem.maybeRepoNameFromSMFile(cwd, base);\n\n return repos\n .reverse()\n .map(makeReposPretty(base))\n .reduce(maybeStickTheRepoToTheTopOfTheList(maybeConfiguredRepoName), [\n createNew,\n ])\n .sort(orderPrompts(maybeConfiguredRepoName));\n}\n\nexport async function maybeExistingRepo(\n cookies: string,\n cwd: string,\n base = DEFAULT_BASE\n): Promise<{ repository: string; existing: boolean }> {\n const token = parsePrismicAuthToken(cookies);\n const repos = await Communication.listRepositories(token);\n\n if (repos.length === 0) {\n const name = await promptForRepoName(base);\n return { existing: false, repository: name };\n }\n\n const choices = sortReposForPrompt(repos, base, cwd);\n\n const numberOfDisabledRepos = choices.filter((repo) => {\n if (repo instanceof Separator) return false;\n return repo.disabled;\n }).length;\n\n const res = await inquirer.prompt<Record<string, string>>([\n {\n type: \"list\",\n name: \"repoName\",\n default: 0,\n required: true,\n message: \"Connect a Prismic Repository or create a new one\",\n choices,\n pageSize: numberOfDisabledRepos + 2 <= 7 ? 7 : numberOfDisabledRepos + 2,\n // loop: false\n },\n ]);\n\n if (res.repoName === CREATE_REPO) {\n const name = await promptForRepoName(base);\n return { existing: false, repository: name };\n }\n return { existing: true, repository: res.repoName };\n}\n","import { Communication, Utils } from \"@slicemachine/core\";\nimport type { Models } from \"@slicemachine/core\";\n\nexport function createRepository(\n domain: string,\n framework: Models.Frameworks,\n config: Models.PrismicSharedConfig\n): Promise<void> {\n const spinner = Utils.spinner(\"Creating Prismic Repository\");\n spinner.start();\n\n return Communication.createRepository(\n domain,\n config.cookies,\n framework,\n config.base\n )\n .then((res) => {\n const addressUrl = new URL(config.base);\n addressUrl.hostname = `${res.data.domain || domain}.${\n addressUrl.hostname\n }`;\n const address = addressUrl.toString();\n spinner.succeed(`We created your new repository ${address}`);\n })\n .catch((error: Error) => {\n spinner.fail(`Error creating repository ${domain}`);\n if (error.message) {\n Utils.writeError(error.message);\n }\n Utils.writeError(`We failed to create you new prismic repository`);\n console.log(`Run ${Utils.bold(\"npx @slicemachine/init\")} again!`);\n process.exit(-1);\n });\n}\n","import { Utils } from \"@slicemachine/core\";\nimport { Models } from \"@slicemachine/core\";\nimport * as inquirer from \"inquirer\";\n\nexport type FrameworkResult = {\n value: Models.Frameworks;\n manuallyAdded: boolean;\n};\n\nexport async function promptForFramework(): Promise<FrameworkResult> {\n const choices = Models.SupportedFrameworks.map((framework) => {\n return {\n name: Utils.Framework.fancyName(framework),\n value: framework,\n };\n });\n\n return inquirer\n .prompt<{ framework: Models.Frameworks }>([\n {\n name: \"framework\",\n type: \"list\",\n message: \"Select a framework to use\",\n required: true,\n choices,\n },\n ])\n .then((res) => {\n return {\n value: res.framework,\n manuallyAdded: true,\n };\n });\n}\n\nexport async function detectFramework(cwd: string): Promise<FrameworkResult> {\n const failMessage = `Please run ${Utils.bold(\n \"npx @slicemachine/init\"\n )} in a Nuxt or Next.js project`;\n\n const spinner = Utils.spinner(\n \"Detecting framework to install correct dependencies\"\n );\n\n spinner.start();\n\n try {\n const maybeFramework = Utils.Framework.defineFramework({\n cwd,\n supportedFrameworks: Object.values(Models.Frameworks),\n });\n\n spinner.stop();\n\n if (!maybeFramework || maybeFramework === Models.Frameworks.vanillajs) {\n Utils.writeError(\"Framework not detected\");\n return await promptForFramework();\n }\n\n const nameToPrint = Utils.Framework.fancyName(maybeFramework);\n\n if (!Utils.Framework.isFrameworkSupported(maybeFramework)) {\n Utils.writeError(`${nameToPrint} is currently not supported`);\n console.log(failMessage);\n process.exit(1);\n }\n\n Utils.writeCheck(`${nameToPrint} detected`);\n\n return {\n value: maybeFramework,\n manuallyAdded: false,\n };\n } catch (error) {\n spinner.fail(\"package.json not found\");\n\n if (error instanceof Error && error.message) {\n Utils.writeError(error.message);\n } else {\n console.log(failMessage);\n }\n\n process.exit(1);\n }\n}\n","import axios from \"axios\";\nimport * as t from \"io-ts\";\nimport { pipe } from \"fp-ts/function\";\nimport { fold } from \"fp-ts/Either\";\nimport { Utils, Models, Communication, FileSystem } from \"@slicemachine/core\";\n\nexport async function getUserProfile(\n cookies: string,\n base = Utils.CONSTS.DEFAULT_BASE\n): Promise<Models.UserProfile> {\n const userServiceBase =\n Utils.CONSTS.DEFAULT_BASE === base\n ? Utils.CONSTS.USER_SERVICE_BASE\n : \"https://user.wroom.io/\";\n\n // note the auth server also provides a userId\n const url = new URL(userServiceBase);\n url.pathname = \"profile\";\n\n const endpoint = url.toString();\n const token = Utils.Cookie.parsePrismicAuthToken(cookies);\n\n return axios\n .get<Models.UserProfile>(endpoint, {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n })\n .then((res) =>\n pipe(\n Models.UserProfile.decode(res.data),\n fold<t.Errors, Models.UserProfile, Models.UserProfile>(\n () => {\n throw new Error(\"Can't parse user profile\");\n },\n (data: Models.UserProfile) => data\n )\n )\n );\n}\n\nexport async function validateSessionAndGetProfile(\n base = Utils.CONSTS.DEFAULT_BASE\n): Promise<{\n info: Models.UserInfo;\n profile: Models.UserProfile | null;\n} | null> {\n const config = FileSystem.PrismicSharedConfigManager.get();\n\n if (!config.cookies.length) return Promise.resolve(null); // default config, logged out.\n if (base != config.base) return Promise.resolve(null); // not the same base so it doesn't\n\n try {\n const info = await Communication.validateSession(config.cookies, base);\n const profile = await getUserProfile(config.cookies, base).catch(\n () => null\n );\n if (profile?.shortId) {\n FileSystem.PrismicSharedConfigManager.setProperties({\n shortId: profile.shortId,\n });\n }\n return { info, profile };\n } catch {\n return null;\n }\n}\n","import { Utils, Auth, Models } from \"@slicemachine/core\";\nimport { validateSessionAndGetProfile } from \"../utils/communication\";\n\nexport async function loginOrBypass(base: string): Promise<{\n info: Models.UserInfo;\n profile: Models.UserProfile | null;\n} | null> {\n const user = await validateSessionAndGetProfile(base).catch((err) =>\n console.log(err)\n );\n if (user) {\n const email = user.info.email;\n Utils.writeCheck(`Logged in as ${Utils.bold(email)}`);\n return user;\n } else {\n await Auth.login(base);\n const user = await validateSessionAndGetProfile(base);\n return user;\n }\n}\n","import { FileSystem, Utils } from \"@slicemachine/core\";\nimport type { Models } from \"@slicemachine/core\";\nimport { FrameworkResult } from \"./detect-framework\";\n\ntype Base = Utils.Endpoints.Base;\n\nexport function configureProject(\n cwd: string,\n base: Base,\n repository: string,\n framework: FrameworkResult,\n sliceLibPath: string[] = [],\n tracking = true\n): void {\n const spinner = Utils.spinner(\n `Configuring your ${framework.value} & Prismic project...`\n );\n spinner.start();\n\n try {\n const manifest = FileSystem.retrieveManifest(cwd);\n\n const manifestUpdated: Models.Manifest = {\n ...(manifest.exists && manifest.content ? manifest.content : {}),\n apiEndpoint: Utils.Endpoints.buildRepositoryEndpoint(base, repository),\n libraries: [\"@/slices\", ...sliceLibPath],\n ...(framework.manuallyAdded ? { framework: framework.value } : {}),\n ...(!tracking ? { tracking } : {}),\n };\n\n if (!manifest.exists) FileSystem.createManifest(cwd, manifestUpdated);\n else FileSystem.patchManifest(cwd, manifestUpdated);\n\n // create the default slices folder if it doesn't exist.\n const pathToSlicesFolder = FileSystem.CustomPaths(cwd)\n .library(\"slices\")\n .value();\n if (!Utils.Files.exists(pathToSlicesFolder))\n Utils.Files.mkdir(pathToSlicesFolder, { recursive: true });\n\n // add slicemachine script to package.json.\n FileSystem.addJsonPackageSmScript(cwd);\n\n spinner.succeed(\"Project configured! Ready to start\");\n } catch {\n spinner.fail(\"Failed to configure Slice Machine\");\n process.exit(-1);\n }\n}\n","import { Utils, FileSystem } from \"@slicemachine/core\";\n\nexport function displayFinalMessage(cwd: string): void {\n const yarnLock = Utils.Files.exists(FileSystem.YarnLockPath(cwd));\n const command = `${yarnLock ? \"yarn\" : \"npm\"} run ${\n Utils.CONSTS.SCRIPT_NAME\n }`;\n\n console.log(\n `${Utils.white(\"■\")} Run ${Utils.purple(\n command\n )} to now launch Slice Machine`\n );\n}\n","import { Utils, FileSystem } from \"@slicemachine/core\";\nimport { execCommand } from \"../utils\";\n\nexport type Dependency = string | { name: string; version: string };\nexport const Dependencies = {\n fromPkgFormat(\n pkgDeps: Record<string, string> | undefined\n ): ReadonlyArray<Dependency> | undefined {\n if (!pkgDeps) return;\n\n return Object.entries(pkgDeps).map(([name, version]) => ({\n name,\n version,\n }));\n },\n};\nfunction formatDeps(dependencies: ReadonlyArray<Dependency>): string {\n return dependencies\n .map((dep) => {\n if (typeof dep === \"string\") return dep;\n return `${dep.name}@${dep.version}`;\n })\n .join(\" \");\n}\n\nexport interface PackageManager {\n install(dependencies: ReadonlyArray<Dependency>): Promise<{ stderr: string }>;\n installDev(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }>;\n}\n\nexport const PackageManager = {\n get(cwd: string): PackageManager {\n if (Utils.Files.exists(FileSystem.YarnLockPath(cwd))) {\n return Yarn;\n }\n return Npm;\n },\n};\n\nexport const Yarn: PackageManager = {\n install(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }> {\n return execCommand(`yarn add ${formatDeps(dependencies)}`);\n },\n installDev(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }> {\n return execCommand(`yarn add --dev ${formatDeps(dependencies)}`);\n },\n};\n\nexport const Npm: PackageManager = {\n install(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }> {\n return execCommand(`npm i --save ${formatDeps(dependencies)}`);\n },\n installDev(\n dependencies: ReadonlyArray<Dependency>\n ): Promise<{ stderr: string }> {\n return execCommand(`npm i --save-dev ${formatDeps(dependencies)}`);\n },\n};\n","import { Utils } from \"@slicemachine/core\";\nimport tmp from \"tmp\";\nimport AdmZip from \"adm-zip\";\nimport fsExtra from \"fs-extra\";\nimport axios from \"axios\";\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { getOrElseW } from \"fp-ts/Either\";\nimport { PackageManager, Dependencies } from \"../utils/PackageManager\";\nimport { PackageJsonHelper } from \"@slicemachine/core/build/src/utils/PackageJson\";\nimport {\n Manifest,\n ManifestHelper,\n} from \"@slicemachine/core/build/src/models/Manifest\";\nimport Files from \"@slicemachine/core/build/src/utils/files\";\nimport Tracker from \"../utils/tracker\";\n\nconst downloadFile = async (reqUrl: string): Promise<string> => {\n const res = await axios.get<Buffer>(reqUrl, { responseType: \"arraybuffer\" });\n\n return new Promise((resolve, reject) => {\n if (res.status == 200) {\n const tmpZipFile = tmp.tmpNameSync();\n const zip = new AdmZip(res.data);\n zip.extractAllTo(tmpZipFile);\n resolve(tmpZipFile);\n } else {\n reject();\n }\n });\n};\n\nfunction toGithubSource(githubPath: string, branch: string): string {\n return `https://codeload.github.com/${githubPath}/zip/${branch}`;\n}\n\nexport async function installLib(\n cwd: string,\n libGithubPath: string,\n branch = \"HEAD\"\n): Promise<string[] | undefined> {\n const spinner = Utils.spinner(\n `Installing the ${libGithubPath} lib in your project...`\n );\n\n try {\n spinner.start();\n\n const [githubUserName, githubProjectName] = libGithubPath.split(\"/\");\n const source = toGithubSource(libGithubPath, branch);\n\n const zipFilePath = await downloadFile(source);\n const outputFolder = `${githubProjectName}-${branch}`;\n const projectPath = path.join(zipFilePath, outputFolder);\n\n const name = `${githubUserName}-${githubProjectName}`;\n const libDestinationFolder = path.join(cwd, name);\n\n // We should be able to offer the ability to override or not an existing library\n if (fs.existsSync(libDestinationFolder)) {\n spinner.succeed(`Lib \"${libGithubPath}\" was already installed (skipped)`);\n return;\n }\n\n // We copy all the slices into the the user project minus the src folder\n fsExtra.moveSync(path.join(projectPath, \"src\"), libDestinationFolder);\n\n // handle dependencies\n const pkgManager = PackageManager.get(cwd);\n const pkgJson = PackageJsonHelper.fromPath(\n path.join(projectPath, \"package.json\")\n );\n if (pkgJson instanceof Error) throw pkgJson;\n\n const dependencies = Dependencies.fromPkgFormat(pkgJson.dependencies);\n if (dependencies) await pkgManager.install(dependencies);\n\n // generate meta file\n Files.write(path.join(libDestinationFolder, \"meta.json\"), {\n name: pkgJson.name,\n });\n\n // retrieve all slices lib paths\n const manifest = Files.readEntity<Error | Manifest>(\n path.join(projectPath, \"sm.json\"),\n (payload: unknown) => {\n return getOrElseW(\n () => new Error(`Unable to parse sm.json from lib ${libGithubPath}`)\n )(Manifest.decode(payload));\n }\n );\n if (manifest instanceof Error) throw manifest;\n\n const localLibs = ManifestHelper.localLibraries(manifest).map(\n ({ path }) => {\n return `~/${name}/${path.replace(\"src/\", \"\")}`;\n }\n );\n\n spinner.succeed(\n `Slice library \"${libGithubPath}\" was installed successfully`\n );\n\n Tracker.get().trackDownloadLibrary(libGithubPath);\n return localLibs;\n } catch (error) {\n spinner.fail(`Error installing ${libGithubPath} lib!`);\n if (error instanceof Error) {\n console.error(error.message);\n }\n process.exit(-1);\n }\n}\n","import { Utils, FileSystem } from \"@slicemachine/core\";\nimport Tracker from \"./utils/tracker\";\n\nimport {\n installRequiredDependencies,\n validatePkg,\n maybeExistingRepo,\n createRepository,\n loginOrBypass,\n configureProject,\n displayFinalMessage,\n detectFramework,\n installLib,\n} from \"./steps\";\nimport { findArgument } from \"./utils\";\n\nasync function init() {\n const cwd = findArgument(process.argv, \"cwd\") || process.cwd();\n const base = findArgument(process.argv, \"base\") || Utils.CONSTS.DEFAULT_BASE;\n const lib: string | undefined = findArgument(process.argv, \"library\");\n const branch: string | undefined = findArgument(process.argv, \"branch\");\n const isTrackingAvailable =\n findArgument(process.argv, \"tracking\") !== \"false\";\n\n Tracker.get().initialize(\n process.env.NEXT_PUBLIC_SEGMENT_KEY || \"JfTfmHaATChc4xueS7RcCBsixI71dJIJ\",\n isTrackingAvailable\n );\n\n Tracker.get().trackInitStart();\n\n console.log(\n Utils.purple(\n \"You're about to configure Slicemachine... Press ctrl + C to cancel\"\n )\n );\n\n // verify package.json file exist\n validatePkg(cwd);\n\n // login\n const user = await loginOrBypass(base);\n if (!user) throw new Error(\"The user should be logged in!\");\n\n // If we get the info from the profile we want to identify all the previous events sent or continue in anonymous mode\n if (user.profile) {\n Tracker.get().identifyUser(user.profile.shortId);\n }\n\n // retrieve tokens for api calls\n const config = FileSystem.PrismicSharedConfigManager.get();\n\n // detect the framework used by the project\n const frameworkResult = await detectFramework(cwd);\n\n // select the repository used with the project.\n const { existing, repository } = await maybeExistingRepo(\n config.cookies,\n cwd,\n config.base\n );\n\n if (!existing) {\n await createRepository(repository, frameworkResult.value, config);\n }\n\n // Install the required dependencies in the project.\n await installRequiredDependencies(cwd, frameworkResult.value);\n\n const sliceLibPath = lib ? await installLib(cwd, lib, branch) : undefined;\n\n // configure the SM.json file and the json package file of the project..\n configureProject(\n cwd,\n base,\n repository,\n frameworkResult,\n sliceLibPath,\n isTrackingAvailable\n );\n\n Tracker.get().trackInitDone(frameworkResult.value, repository);\n\n // Ask the user to run slice-machine.\n displayFinalMessage(cwd);\n}\n\ntry {\n void init();\n} catch (error) {\n if (error instanceof Error) Utils.writeError(error.message);\n else console.error(error);\n}\n"],"names":["uuidv4","ServerAnalytics","util","exec","Utils","Models","FileSystem","path","inquirer","Communication","Separator","parsePrismicAuthToken","axios","pipe","fold","Auth","tmp","AdmZip","fs","PackageJsonHelper","Files","getOrElseW","Manifest","ManifestHelper"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slicemachine/init",
3
- "version": "1.1.1-alpha.2",
3
+ "version": "1.1.1-alpha.20",
4
4
  "description": "The easiest way to add Slice Machine to your project",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -18,7 +18,7 @@
18
18
  "watch": "tsc --project tsconfig.json --noEmit --watch"
19
19
  },
20
20
  "dependencies": {
21
- "@slicemachine/core": "1.1.1-alpha.2",
21
+ "@slicemachine/core": "1.1.1-alpha.20",
22
22
  "adm-zip": "^0.5.9",
23
23
  "analytics-node": "^6.0.0",
24
24
  "axios": "^0.24.0",
@@ -26,7 +26,8 @@
26
26
  "fs-extra": "^10.0.0",
27
27
  "inquirer": "^8.2.0",
28
28
  "io-ts": "^2.2.16",
29
- "tmp": "^0.2.1"
29
+ "tmp": "^0.2.1",
30
+ "uuid": "^8.3.2"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@babel/core": "^7.15.8",
@@ -39,6 +40,7 @@
39
40
  "@types/inquirer": "^8.1.3",
40
41
  "@types/jest": "^27.0.2",
41
42
  "@types/tmp": "^0.2.2",
43
+ "@types/uuid": "^8.3.4",
42
44
  "@typescript-eslint/eslint-plugin": "^5.10.0",
43
45
  "@typescript-eslint/parser": "^5.10.0",
44
46
  "babel-jest": "^27.0.2",
@@ -59,5 +61,5 @@
59
61
  "engines": {
60
62
  "node": ">=12"
61
63
  },
62
- "gitHead": "44982775c09a3918e73c3f6513cda8a17573f07b"
64
+ "gitHead": "76d096b7df288c36c53c4ac3e934523b3b6ab03d"
63
65
  }
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Utils, FileSystem } from "@slicemachine/core";
2
- import { Tracker } from "./utils/tracker";
2
+ import Tracker from "./utils/tracker";
3
+
3
4
  import {
4
5
  installRequiredDependencies,
5
6
  validatePkg,
@@ -19,7 +20,14 @@ async function init() {
19
20
  const lib: string | undefined = findArgument(process.argv, "library");
20
21
  const branch: string | undefined = findArgument(process.argv, "branch");
21
22
  const isTrackingAvailable =
22
- findArgument(process.argv, "tracking") === "false" ? false : true;
23
+ findArgument(process.argv, "tracking") !== "false";
24
+
25
+ Tracker.get().initialize(
26
+ process.env.NEXT_PUBLIC_SEGMENT_KEY || "JfTfmHaATChc4xueS7RcCBsixI71dJIJ",
27
+ isTrackingAvailable
28
+ );
29
+
30
+ Tracker.get().trackInitStart();
23
31
 
24
32
  console.log(
25
33
  Utils.purple(
@@ -34,6 +42,11 @@ async function init() {
34
42
  const user = await loginOrBypass(base);
35
43
  if (!user) throw new Error("The user should be logged in!");
36
44
 
45
+ // If we get the info from the profile we want to identify all the previous events sent or continue in anonymous mode
46
+ if (user.profile) {
47
+ Tracker.get().identifyUser(user.profile.shortId);
48
+ }
49
+
37
50
  // retrieve tokens for api calls
38
51
  const config = FileSystem.PrismicSharedConfigManager.get();
39
52
 
@@ -41,46 +54,34 @@ async function init() {
41
54
  const frameworkResult = await detectFramework(cwd);
42
55
 
43
56
  // select the repository used with the project.
44
- const { existing, name } = await maybeExistingRepo(
57
+ const { existing, repository } = await maybeExistingRepo(
45
58
  config.cookies,
46
59
  cwd,
47
60
  config.base
48
61
  );
49
62
 
50
63
  if (!existing) {
51
- await createRepository(name, frameworkResult.value, config);
64
+ await createRepository(repository, frameworkResult.value, config);
52
65
  }
53
66
 
54
- const tracker = user.profile?.shortId
55
- ? Tracker.build(
56
- process.env.NEXT_PUBLIC_SEGMENT_KEY ||
57
- "JfTfmHaATChc4xueS7RcCBsixI71dJIJ",
58
- name,
59
- {
60
- userId: user.profile.shortId,
61
- },
62
- isTrackingAvailable
63
- )
64
- : undefined;
65
-
66
- // install the required dependencies in the project.
67
+ // Install the required dependencies in the project.
67
68
  await installRequiredDependencies(cwd, frameworkResult.value);
68
69
 
69
- const sliceLibPath = lib
70
- ? await installLib(tracker, cwd, lib, branch)
71
- : undefined;
70
+ const sliceLibPath = lib ? await installLib(cwd, lib, branch) : undefined;
72
71
 
73
72
  // configure the SM.json file and the json package file of the project..
74
73
  configureProject(
75
74
  cwd,
76
75
  base,
77
- name,
76
+ repository,
78
77
  frameworkResult,
79
78
  sliceLibPath,
80
79
  isTrackingAvailable
81
80
  );
82
81
 
83
- // ask the user to run slice-machine.
82
+ Tracker.get().trackInitDone(frameworkResult.value, repository);
83
+
84
+ // Ask the user to run slice-machine.
84
85
  displayFinalMessage(cwd);
85
86
  }
86
87
 
@@ -43,7 +43,7 @@ export function configureProject(
43
43
 
44
44
  spinner.succeed("Project configured! Ready to start");
45
45
  } catch {
46
- spinner.fail("Failed to configure your Prismic Local Builder");
46
+ spinner.fail("Failed to configure Slice Machine");
47
47
  process.exit(-1);
48
48
  }
49
49
  }
@@ -29,7 +29,7 @@ export function createRepository(
29
29
  Utils.writeError(error.message);
30
30
  }
31
31
  Utils.writeError(`We failed to create you new prismic repository`);
32
- console.log(`Run ${Utils.bold("npx slicemachine init")} again!`);
32
+ console.log(`Run ${Utils.bold("npx @slicemachine/init")} again!`);
33
33
  process.exit(-1);
34
34
  });
35
35
  }
@@ -35,7 +35,7 @@ export async function promptForFramework(): Promise<FrameworkResult> {
35
35
 
36
36
  export async function detectFramework(cwd: string): Promise<FrameworkResult> {
37
37
  const failMessage = `Please run ${Utils.bold(
38
- "npx slicemachine init"
38
+ "npx @slicemachine/init"
39
39
  )} in a Nuxt or Next.js project`;
40
40
 
41
41
  const spinner = Utils.spinner(
@@ -9,6 +9,6 @@ export function displayFinalMessage(cwd: string): void {
9
9
  console.log(
10
10
  `${Utils.white("■")} Run ${Utils.purple(
11
11
  command
12
- )} to now launch your Local Builder`
12
+ )} to now launch Slice Machine`
13
13
  );
14
14
  }
@@ -14,7 +14,7 @@ import {
14
14
  ManifestHelper,
15
15
  } from "@slicemachine/core/build/src/models/Manifest";
16
16
  import Files from "@slicemachine/core/build/src/utils/files";
17
- import { Tracker } from "../utils/tracker";
17
+ import Tracker from "../utils/tracker";
18
18
 
19
19
  const downloadFile = async (reqUrl: string): Promise<string> => {
20
20
  const res = await axios.get<Buffer>(reqUrl, { responseType: "arraybuffer" });
@@ -36,7 +36,6 @@ function toGithubSource(githubPath: string, branch: string): string {
36
36
  }
37
37
 
38
38
  export async function installLib(
39
- tracker: Tracker | undefined,
40
39
  cwd: string,
41
40
  libGithubPath: string,
42
41
  branch = "HEAD"
@@ -103,7 +102,7 @@ export async function installLib(
103
102
  `Slice library "${libGithubPath}" was installed successfully`
104
103
  );
105
104
 
106
- tracker?.Track.downloadLibrary(libGithubPath);
105
+ Tracker.get().trackDownloadLibrary(libGithubPath);
107
106
  return localLibs;
108
107
  } catch (error) {
109
108
  spinner.fail(`Error installing ${libGithubPath} lib!`);
@@ -43,7 +43,7 @@ export async function installRequiredDependencies(
43
43
  : "npm install --save-dev";
44
44
  const installDependencyCommand = yarnLock ? "yarn add" : "npm install --save";
45
45
 
46
- const spinner = Utils.spinner("Downloading Prismic Visual Builder");
46
+ const spinner = Utils.spinner("Downloading Slice Machine");
47
47
  spinner.start();
48
48
 
49
49
  const { stderr } = await execCommand(
@@ -60,7 +60,7 @@ export async function installRequiredDependencies(
60
60
  const isPackageInstalled = Utils.Files.exists(pathToPkg);
61
61
 
62
62
  if (isPackageInstalled || !stderr.length) {
63
- spinner.succeed("The Prismic Visual Builder was installed successfully");
63
+ spinner.succeed("Slice Machine was installed successfully");
64
64
  return;
65
65
  }
66
66
 
@@ -1,12 +1,9 @@
1
- import { Utils, Communication, Auth } from "@slicemachine/core";
2
- import {
3
- validateSessionAndGetProfile,
4
- UserProfile,
5
- } from "../utils/communication";
1
+ import { Utils, Auth, Models } from "@slicemachine/core";
2
+ import { validateSessionAndGetProfile } from "../utils/communication";
6
3
 
7
4
  export async function loginOrBypass(base: string): Promise<{
8
- info: Communication.UserInfo;
9
- profile: UserProfile | null;
5
+ info: Models.UserInfo;
6
+ profile: Models.UserProfile | null;
10
7
  } | null> {
11
8
  const user = await validateSessionAndGetProfile(base).catch((err) =>
12
9
  console.log(err)
@@ -1,8 +1,6 @@
1
1
  import * as inquirer from "inquirer";
2
2
  import Separator from "inquirer/lib/objects/separator";
3
- import { Communication, Utils, FileSystem } from "@slicemachine/core";
4
- import { Repositories } from "@slicemachine/core/src/models/Repositories";
5
- import { Repository } from "@slicemachine/core/src/models/Repository";
3
+ import { Communication, Utils, FileSystem, Models } from "@slicemachine/core";
6
4
  import { parsePrismicAuthToken } from "@slicemachine/core/build/src/utils/cookie";
7
5
 
8
6
  export const CREATE_REPO = "$_CREATE_REPO"; // not a valid domain name
@@ -50,10 +48,10 @@ export type PromptOrSeparator = RepoPrompt | Separator;
50
48
  export type RepoPrompts = Array<PromptOrSeparator>;
51
49
 
52
50
  export function makeReposPretty(base: string) {
53
- return function ({ name, domain, role }: Repository): RepoPrompt {
51
+ return function ({ name, domain, role }: Models.Repository): RepoPrompt {
54
52
  const address = new URL(base);
55
53
  address.hostname = `${domain}.${address.hostname}`;
56
- if (Utils.roles.canUpdateCustomTypes(role) === false) {
54
+ if (Models.canUpdateCustomTypes(role) === false) {
57
55
  return {
58
56
  name: `${Utils.purple.dim("Use")} ${Utils.bold.dim(
59
57
  name
@@ -93,7 +91,7 @@ export function maybeStickTheRepoToTheTopOfTheList(repoName?: string | null) {
93
91
  }
94
92
 
95
93
  export function sortReposForPrompt(
96
- repos: Repositories,
94
+ repos: Models.Repositories,
97
95
  base: string,
98
96
  cwd: string
99
97
  ): RepoPrompts {
@@ -119,13 +117,13 @@ export async function maybeExistingRepo(
119
117
  cookies: string,
120
118
  cwd: string,
121
119
  base = DEFAULT_BASE
122
- ): Promise<{ name: string; existing: boolean }> {
120
+ ): Promise<{ repository: string; existing: boolean }> {
123
121
  const token = parsePrismicAuthToken(cookies);
124
122
  const repos = await Communication.listRepositories(token);
125
123
 
126
124
  if (repos.length === 0) {
127
125
  const name = await promptForRepoName(base);
128
- return { existing: false, name };
126
+ return { existing: false, repository: name };
129
127
  }
130
128
 
131
129
  const choices = sortReposForPrompt(repos, base, cwd);
@@ -150,7 +148,7 @@ export async function maybeExistingRepo(
150
148
 
151
149
  if (res.repoName === CREATE_REPO) {
152
150
  const name = await promptForRepoName(base);
153
- return { existing: false, name };
151
+ return { existing: false, repository: name };
154
152
  }
155
- return { existing: true, name: res.repoName };
153
+ return { existing: true, repository: res.repoName };
156
154
  }
@@ -2,47 +2,38 @@ import axios from "axios";
2
2
  import * as t from "io-ts";
3
3
  import { pipe } from "fp-ts/function";
4
4
  import { fold } from "fp-ts/Either";
5
- import { Utils, Communication, FileSystem } from "@slicemachine/core";
6
-
7
- const UserProfile = t.exact(
8
- t.type({
9
- userId: t.string,
10
- shortId: t.string,
11
- email: t.string,
12
- firstName: t.string,
13
- lastName: t.string,
14
- })
15
- );
16
-
17
- export type UserProfile = t.TypeOf<typeof UserProfile>;
5
+ import { Utils, Models, Communication, FileSystem } from "@slicemachine/core";
18
6
 
19
7
  export async function getUserProfile(
20
8
  cookies: string,
21
9
  base = Utils.CONSTS.DEFAULT_BASE
22
- ): Promise<UserProfile> {
23
- // note the auth server also provides a userId
10
+ ): Promise<Models.UserProfile> {
11
+ const userServiceBase =
12
+ Utils.CONSTS.DEFAULT_BASE === base
13
+ ? Utils.CONSTS.USER_SERVICE_BASE
14
+ : "https://user.wroom.io/";
24
15
 
25
- const url = new URL(base);
26
- url.hostname = `user.${url.hostname}`;
16
+ // note the auth server also provides a userId
17
+ const url = new URL(userServiceBase);
27
18
  url.pathname = "profile";
28
19
 
29
20
  const endpoint = url.toString();
30
21
  const token = Utils.Cookie.parsePrismicAuthToken(cookies);
31
22
 
32
23
  return axios
33
- .get<UserProfile>(endpoint, {
24
+ .get<Models.UserProfile>(endpoint, {
34
25
  headers: {
35
- Authorization: `Bearer Token ${token}`,
26
+ Authorization: `Bearer ${token}`,
36
27
  },
37
28
  })
38
29
  .then((res) =>
39
30
  pipe(
40
- UserProfile.decode(res.data),
41
- fold<t.Errors, UserProfile, UserProfile>(
31
+ Models.UserProfile.decode(res.data),
32
+ fold<t.Errors, Models.UserProfile, Models.UserProfile>(
42
33
  () => {
43
34
  throw new Error("Can't parse user profile");
44
35
  },
45
- (data: UserProfile) => data
36
+ (data: Models.UserProfile) => data
46
37
  )
47
38
  )
48
39
  );
@@ -51,8 +42,8 @@ export async function getUserProfile(
51
42
  export async function validateSessionAndGetProfile(
52
43
  base = Utils.CONSTS.DEFAULT_BASE
53
44
  ): Promise<{
54
- info: Communication.UserInfo;
55
- profile: UserProfile | null;
45
+ info: Models.UserInfo;
46
+ profile: Models.UserProfile | null;
56
47
  } | null> {
57
48
  const config = FileSystem.PrismicSharedConfigManager.get();
58
49
 
@@ -1,57 +1,115 @@
1
- /*
2
- * DUPLICATION
3
- * this file is a duplication of ServerTracker in sm-ui
4
- * this duplication has been done on purpose to simplify the merge if init becomes part of sm-ui
5
- * or if we decide to share the tracker implementation from a lib, but it'll need some refactoring
6
- * Duplication means no entanglement so don't merge this with the other implem and keep the structure.
7
- */
8
-
9
1
  import ServerAnalytics from "analytics-node";
2
+ import { v4 as uuidv4 } from "uuid";
3
+ import { Frameworks } from "@slicemachine/core/build/src/models";
10
4
 
11
5
  export enum EventType {
12
6
  DownloadLibrary = "SliceMachine Download Library",
7
+ InitStart = "SliceMachine Init Start",
8
+ InitDone = "SliceMachine Init Done",
13
9
  }
14
10
 
15
- export class Tracker {
16
- constructor(
17
- readonly analytics: ServerAnalytics,
18
- readonly repo: string,
19
- readonly identifier: { userId: string } | { anonymousId: string },
20
- readonly tracking = true
21
- ) {}
22
-
23
- static build(
24
- writeKey: string,
25
- repo: string | undefined,
26
- identifier: { userId: string } | { anonymousId: string },
27
- tracking = true
28
- ): Tracker | undefined {
11
+ type SegmentIdentifier = { userId: string } | { anonymousId: string };
12
+
13
+ export class InitTracker {
14
+ #client: ServerAnalytics | null = null;
15
+ #isTrackingActive = true;
16
+ #anonymousId = "";
17
+ #userId: string | null = null;
18
+
19
+ initialize(segmentKey: string, isTrackingActive = true): void {
29
20
  try {
30
- if (!repo) return;
31
- const analytics = new ServerAnalytics(writeKey);
32
- return new Tracker(analytics, repo, identifier, tracking);
21
+ // The initialize method cannot be used for changing some class properties
22
+ if (!!this.#client) return;
23
+
24
+ this.#isTrackingActive = isTrackingActive;
25
+ this.#anonymousId = uuidv4();
26
+ this.#client = new ServerAnalytics(segmentKey);
33
27
  } catch (error) {
34
- console.warn(error);
35
- return;
28
+ // If the client is not correctly setup we are silently failing as the tracker is not a critical feature
36
29
  }
37
30
  }
38
31
 
39
- private trackEvent(
32
+ /** Private methods **/
33
+
34
+ _trackEvent(
40
35
  eventType: EventType,
41
36
  attributes: Record<string, unknown> = {}
42
37
  ): void {
43
- this.tracking &&
44
- this.analytics.track({
38
+ if (!this._isTrackingPossible(this.#client)) {
39
+ return;
40
+ }
41
+
42
+ const identifier = this._createSegmentIdentifier();
43
+
44
+ try {
45
+ this.#client.track({
45
46
  event: eventType,
46
- ...this.identifier,
47
+ ...identifier,
47
48
  properties: attributes,
48
49
  });
50
+ } catch {
51
+ // If the client is not correctly setup we are silently failing as the tracker is not a critical feature
52
+ }
53
+ }
54
+
55
+ _identifyEvent(userId: string): void {
56
+ if (!this._isTrackingPossible(this.#client)) {
57
+ return;
58
+ }
59
+
60
+ try {
61
+ this.#client.identify({
62
+ userId,
63
+ anonymousId: this.#anonymousId,
64
+ });
65
+ } catch {
66
+ // If the client is not correctly setup we are silently failing as the tracker is not a critical feature
67
+ }
68
+ }
69
+
70
+ _isTrackingPossible(
71
+ client: ServerAnalytics | null
72
+ ): client is ServerAnalytics {
73
+ return !!client && this.#isTrackingActive;
74
+ }
75
+
76
+ _createSegmentIdentifier(): SegmentIdentifier {
77
+ return !!this.#userId
78
+ ? { userId: this.#userId }
79
+ : { anonymousId: this.#anonymousId };
80
+ }
81
+
82
+ /** Public methods **/
83
+
84
+ identifyUser(userId: string): void {
85
+ this.#userId = userId;
86
+ this._identifyEvent(userId);
87
+ }
88
+
89
+ trackDownloadLibrary(library: string): void {
90
+ this._trackEvent(EventType.DownloadLibrary, { library });
49
91
  }
50
92
 
51
- Track = {
52
- // not called, for demo only
53
- downloadLibrary: (library: string): void => {
54
- this.trackEvent(EventType.DownloadLibrary, { library });
93
+ trackInitStart(): void {
94
+ this._trackEvent(EventType.InitStart);
95
+ }
96
+
97
+ trackInitDone(framework: Frameworks, repo: string): void {
98
+ this._trackEvent(EventType.InitDone, { framework, repo });
99
+ }
100
+ }
101
+
102
+ const Tracker = (() => {
103
+ let smTrackerInstance: InitTracker;
104
+
105
+ const init = () => new InitTracker();
106
+
107
+ return {
108
+ get() {
109
+ if (!smTrackerInstance) smTrackerInstance = init();
110
+ return smTrackerInstance;
55
111
  },
56
112
  };
57
- }
113
+ })();
114
+
115
+ export default Tracker;