@slicemachine/manager 0.1.1-dev-plugins.11 → 0.1.1-dev-plugins.12

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 (57) hide show
  1. package/README.md +85 -0
  2. package/dist/constants/API_ENDPOINTS.cjs.map +1 -1
  3. package/dist/constants/API_ENDPOINTS.d.ts +1 -2
  4. package/dist/constants/API_ENDPOINTS.js.map +1 -1
  5. package/dist/errors.cjs.map +1 -1
  6. package/dist/errors.d.ts +1 -1
  7. package/dist/errors.js.map +1 -1
  8. package/dist/lib/decodePackageJSON.cjs +29 -0
  9. package/dist/lib/decodePackageJSON.cjs.map +1 -0
  10. package/dist/lib/decodePackageJSON.d.ts +12 -0
  11. package/dist/lib/decodePackageJSON.js +12 -0
  12. package/dist/lib/decodePackageJSON.js.map +1 -0
  13. package/dist/lib/locateFileUpward.cjs +8 -11
  14. package/dist/lib/locateFileUpward.cjs.map +1 -1
  15. package/dist/lib/locateFileUpward.js +8 -11
  16. package/dist/lib/locateFileUpward.js.map +1 -1
  17. package/dist/managers/SliceMachineManager.cjs +4 -0
  18. package/dist/managers/SliceMachineManager.cjs.map +1 -1
  19. package/dist/managers/SliceMachineManager.d.ts +2 -0
  20. package/dist/managers/SliceMachineManager.js +4 -0
  21. package/dist/managers/SliceMachineManager.js.map +1 -1
  22. package/dist/managers/createSliceMachineManager.cjs +2 -2
  23. package/dist/managers/createSliceMachineManager.cjs.map +1 -1
  24. package/dist/managers/createSliceMachineManager.d.ts +4 -3
  25. package/dist/managers/createSliceMachineManager.js +2 -2
  26. package/dist/managers/createSliceMachineManager.js.map +1 -1
  27. package/dist/managers/slices/SlicesManager.cjs +21 -4
  28. package/dist/managers/slices/SlicesManager.cjs.map +1 -1
  29. package/dist/managers/slices/SlicesManager.d.ts +1 -1
  30. package/dist/managers/slices/SlicesManager.js +21 -4
  31. package/dist/managers/slices/SlicesManager.js.map +1 -1
  32. package/dist/managers/telemetry/TelemetryManager.cjs +3 -1
  33. package/dist/managers/telemetry/TelemetryManager.cjs.map +1 -1
  34. package/dist/managers/telemetry/TelemetryManager.js +3 -1
  35. package/dist/managers/telemetry/TelemetryManager.js.map +1 -1
  36. package/dist/managers/user/UserManager.cjs +6 -2
  37. package/dist/managers/user/UserManager.cjs.map +1 -1
  38. package/dist/managers/user/UserManager.d.ts +2 -0
  39. package/dist/managers/user/UserManager.js +6 -2
  40. package/dist/managers/user/UserManager.js.map +1 -1
  41. package/dist/managers/versions/VersionsManager.cjs +14 -3
  42. package/dist/managers/versions/VersionsManager.cjs.map +1 -1
  43. package/dist/managers/versions/VersionsManager.js +14 -3
  44. package/dist/managers/versions/VersionsManager.js.map +1 -1
  45. package/dist/managers/versions/types.d.ts +1 -1
  46. package/package.json +7 -5
  47. package/src/constants/API_ENDPOINTS.ts +1 -1
  48. package/src/errors.ts +1 -74
  49. package/src/lib/decodePackageJSON.ts +18 -0
  50. package/src/lib/locateFileUpward.ts +8 -12
  51. package/src/managers/SliceMachineManager.ts +6 -0
  52. package/src/managers/createSliceMachineManager.ts +3 -3
  53. package/src/managers/slices/SlicesManager.ts +24 -7
  54. package/src/managers/telemetry/TelemetryManager.ts +6 -0
  55. package/src/managers/user/UserManager.ts +12 -0
  56. package/src/managers/versions/VersionsManager.ts +22 -6
  57. package/src/managers/versions/types.ts +1 -1
@@ -7,6 +7,7 @@ var __publicField = (obj, key, value) => {
7
7
  import * as fs from "node:fs/promises";
8
8
  import * as path from "node:path";
9
9
  import semver from "semver";
10
+ import { decodePackageJSON } from "../../lib/decodePackageJSON.js";
10
11
  import { fetchGitHubReleaseBodyForRelease } from "../../lib/fetchGitHubReleaseBodyForRelease.js";
11
12
  import { fetchNPMPackageVersions } from "../../lib/fetchNPMPackageVersions.js";
12
13
  import { SLICE_MACHINE_GITHUB_PACKAGE_NAME } from "../../constants/SLICE_MACHINE_GITHUB_PACKAGE_NAME.js";
@@ -19,7 +20,9 @@ const detectVersionBumpKind = (to, from) => {
19
20
  if (!from) {
20
21
  return VERSION_KIND.FIRST;
21
22
  }
22
- if (semver.satisfies(to, `~${from}`)) {
23
+ if (semver.eq(to, from)) {
24
+ return void 0;
25
+ } else if (semver.satisfies(to, `~${from}`)) {
23
26
  return VERSION_KIND.PATCH;
24
27
  } else if (semver.satisfies(to, `^${from}`)) {
25
28
  return VERSION_KIND.MINOR;
@@ -38,8 +41,16 @@ class VersionsManager extends BaseManager {
38
41
  async getRunningSliceMachineVersion() {
39
42
  const sliceMachineDir = await this.project.locateSliceMachineUIDir();
40
43
  const sliceMachinePackageJSONContents = await fs.readFile(path.join(sliceMachineDir, "package.json"), "utf8");
41
- const json = JSON.parse(sliceMachinePackageJSONContents);
42
- return json.version;
44
+ let sliceMachinePackageJSON;
45
+ try {
46
+ sliceMachinePackageJSON = JSON.parse(sliceMachinePackageJSONContents);
47
+ } catch {
48
+ }
49
+ const { value, error } = decodePackageJSON(sliceMachinePackageJSON);
50
+ if (error) {
51
+ throw new Error(`Invalid ${SLICE_MACHINE_NPM_PACKAGE_NAME} \`package.json\` file. ${error.errors.join(", ")}`);
52
+ }
53
+ return value.version;
43
54
  }
44
55
  async getAllStableSliceMachineVersions() {
45
56
  const versions = await fetchNPMPackageVersions({
@@ -1 +1 @@
1
- {"version":3,"file":"VersionsManager.js","sources":["../../../../src/managers/versions/VersionsManager.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport semver from \"semver\";\n\nimport {\n\tfetchGitHubReleaseBodyForRelease,\n\tGitHubReleaseMetadata,\n} from \"../../lib/fetchGitHubReleaseBodyForRelease\";\nimport { fetchNPMPackageVersions } from \"../../lib/fetchNPMPackageVersions\";\n\nimport { SLICE_MACHINE_GITHUB_PACKAGE_NAME } from \"../../constants/SLICE_MACHINE_GITHUB_PACKAGE_NAME\";\nimport { SLICE_MACHINE_GITHUB_REPOSITORY_NAME } from \"../../constants/SLICE_MACHINE_GITHUB_REPOSITORY_NAME\";\nimport { SLICE_MACHINE_GITHUB_REPOSITORY_ORGANIZATION } from \"../../constants/SLICE_MACHINE_GITHUB_REPOSITORY_ORGANIZATION\";\nimport { SLICE_MACHINE_NPM_PACKAGE_NAME } from \"../../constants/SLICE_MACHINE_NPM_PACKAGE_NAME\";\nimport { VERSION_KIND } from \"../../constants/VERSION_KIND\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport { Version } from \"./types\";\n\nconst detectVersionBumpKind = (\n\tto: string,\n\tfrom?: string,\n): typeof VERSION_KIND[keyof typeof VERSION_KIND] => {\n\tif (!from) {\n\t\treturn VERSION_KIND.FIRST;\n\t}\n\n\tif (semver.satisfies(to, `~${from}`)) {\n\t\treturn VERSION_KIND.PATCH;\n\t} else if (semver.satisfies(to, `^${from}`)) {\n\t\treturn VERSION_KIND.MINOR;\n\t} else {\n\t\treturn VERSION_KIND.MAJOR;\n\t}\n};\n\ntype SliceMachineManagerGetReleaseNotesForVersionArgs = {\n\tversion: string;\n};\n\nexport class VersionsManager extends BaseManager {\n\t/**\n\t * Record of version numbers mapped to their GitHub release metadata.\n\t */\n\tgitHubSliceMachineReleaseMetadataCache: Record<\n\t\tstring,\n\t\tGitHubReleaseMetadata | undefined\n\t> = {};\n\n\tasync getRunningSliceMachineVersion(): Promise<string> {\n\t\tconst sliceMachineDir = await this.project.locateSliceMachineUIDir();\n\n\t\tconst sliceMachinePackageJSONContents = await fs.readFile(\n\t\t\tpath.join(sliceMachineDir, \"package.json\"),\n\t\t\t\"utf8\",\n\t\t);\n\n\t\t// TODO: Validate the contents? This code currently assumes a\n\t\t// well-formed document.\n\t\tconst json = JSON.parse(sliceMachinePackageJSONContents);\n\n\t\treturn json.version;\n\t}\n\n\tasync getAllStableSliceMachineVersions(): Promise<string[]> {\n\t\tconst versions = await fetchNPMPackageVersions({\n\t\t\tpackageName: SLICE_MACHINE_NPM_PACKAGE_NAME,\n\t\t});\n\n\t\tconst filteredVersions = versions.filter((version) => {\n\t\t\t// Exclude tagged versions (e.g. `1.0.0-alpha.0`).\n\t\t\t// Exclude versions < 0.1.0 (e.g. `0.0.1`).\n\t\t\treturn (\n\t\t\t\t/^[1-9]\\d*\\.\\d+\\.\\d+$/.test(version) ||\n\t\t\t\t/^\\d+\\.[1-9]\\d*\\.\\d+$/.test(version)\n\t\t\t);\n\t\t});\n\n\t\treturn semver.rsort(filteredVersions);\n\t}\n\n\tasync getAllStableSliceMachineVersionsWithKind(): Promise<Version[]> {\n\t\tconst versions = await this.getAllStableSliceMachineVersions();\n\n\t\treturn versions.map((version, i) => {\n\t\t\tconst previousVersion = versions[i + 1];\n\n\t\t\treturn {\n\t\t\t\tversion,\n\t\t\t\tkind: detectVersionBumpKind(version, previousVersion),\n\t\t\t};\n\t\t});\n\t}\n\n\tasync getLatestNonBreakingSliceMachineVersion(): Promise<string | undefined> {\n\t\tconst versions = await this.getAllStableSliceMachineVersions();\n\t\tconst currentVersion = await this.getRunningSliceMachineVersion();\n\n\t\treturn semver.maxSatisfying(versions, `^${currentVersion}`) ?? undefined;\n\t}\n\n\tasync checkIsUpdateAvailable(): Promise<boolean> {\n\t\tconst versions = await this.getAllStableSliceMachineVersions();\n\t\tconst currentVersion = await this.getRunningSliceMachineVersion();\n\n\t\treturn semver.gt(versions[0], currentVersion);\n\t}\n\n\tasync getSliceMachineReleaseNotesForVersion(\n\t\targs: SliceMachineManagerGetReleaseNotesForVersionArgs,\n\t): Promise<string | undefined> {\n\t\treturn await fetchGitHubReleaseBodyForRelease({\n\t\t\trepositoryOwner: SLICE_MACHINE_GITHUB_REPOSITORY_ORGANIZATION,\n\t\t\trepositoryName: SLICE_MACHINE_GITHUB_REPOSITORY_NAME,\n\t\t\tpackageName: SLICE_MACHINE_GITHUB_PACKAGE_NAME,\n\t\t\tversion: args.version,\n\t\t\tcache: this.gitHubSliceMachineReleaseMetadataCache,\n\t\t});\n\t}\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAoBA,MAAM,wBAAwB,CAC7B,IACA,SACmD;AACnD,MAAI,CAAC,MAAM;AACV,WAAO,aAAa;AAAA,EACpB;AAED,MAAI,OAAO,UAAU,IAAI,IAAI,MAAM,GAAG;AACrC,WAAO,aAAa;AAAA,EAAA,WACV,OAAO,UAAU,IAAI,IAAI,MAAM,GAAG;AAC5C,WAAO,aAAa;AAAA,EAAA,OACd;AACN,WAAO,aAAa;AAAA,EACpB;AACF;AAMM,MAAO,wBAAwB,YAAW;AAAA,EAA1C;AAAA;AAIL;AAAA;AAAA;AAAA,kEAGI,CAAA;AAAA;AAAA,EAEJ,MAAM,gCAA6B;AAClC,UAAM,kBAAkB,MAAM,KAAK,QAAQ,wBAAuB;AAE5D,UAAA,kCAAkC,MAAM,GAAG,SAChD,KAAK,KAAK,iBAAiB,cAAc,GACzC,MAAM;AAKD,UAAA,OAAO,KAAK,MAAM,+BAA+B;AAEvD,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,MAAM,mCAAgC;AAC/B,UAAA,WAAW,MAAM,wBAAwB;AAAA,MAC9C,aAAa;AAAA,IAAA,CACb;AAED,UAAM,mBAAmB,SAAS,OAAO,CAAC,YAAW;AAGpD,aACC,uBAAuB,KAAK,OAAO,KACnC,uBAAuB,KAAK,OAAO;AAAA,IAAA,CAEpC;AAEM,WAAA,OAAO,MAAM,gBAAgB;AAAA,EACrC;AAAA,EAEA,MAAM,2CAAwC;AACvC,UAAA,WAAW,MAAM,KAAK;AAE5B,WAAO,SAAS,IAAI,CAAC,SAAS,MAAK;AAC5B,YAAA,kBAAkB,SAAS,IAAI,CAAC;AAE/B,aAAA;AAAA,QACN;AAAA,QACA,MAAM,sBAAsB,SAAS,eAAe;AAAA,MAAA;AAAA,KAErD;AAAA,EACF;AAAA,EAEA,MAAM,0CAAuC;AACtC,UAAA,WAAW,MAAM,KAAK;AACtB,UAAA,iBAAiB,MAAM,KAAK;AAElC,WAAO,OAAO,cAAc,UAAU,IAAI,gBAAgB,KAAK;AAAA,EAChE;AAAA,EAEA,MAAM,yBAAsB;AACrB,UAAA,WAAW,MAAM,KAAK;AACtB,UAAA,iBAAiB,MAAM,KAAK;AAElC,WAAO,OAAO,GAAG,SAAS,CAAC,GAAG,cAAc;AAAA,EAC7C;AAAA,EAEA,MAAM,sCACL,MAAsD;AAEtD,WAAO,MAAM,iCAAiC;AAAA,MAC7C,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,IAAA,CACZ;AAAA,EACF;AACA;"}
1
+ {"version":3,"file":"VersionsManager.js","sources":["../../../../src/managers/versions/VersionsManager.ts"],"sourcesContent":["import * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport semver from \"semver\";\n\nimport { decodePackageJSON } from \"../../lib/decodePackageJSON\";\nimport {\n\tfetchGitHubReleaseBodyForRelease,\n\tGitHubReleaseMetadata,\n} from \"../../lib/fetchGitHubReleaseBodyForRelease\";\nimport { fetchNPMPackageVersions } from \"../../lib/fetchNPMPackageVersions\";\n\nimport { SLICE_MACHINE_GITHUB_PACKAGE_NAME } from \"../../constants/SLICE_MACHINE_GITHUB_PACKAGE_NAME\";\nimport { SLICE_MACHINE_GITHUB_REPOSITORY_NAME } from \"../../constants/SLICE_MACHINE_GITHUB_REPOSITORY_NAME\";\nimport { SLICE_MACHINE_GITHUB_REPOSITORY_ORGANIZATION } from \"../../constants/SLICE_MACHINE_GITHUB_REPOSITORY_ORGANIZATION\";\nimport { SLICE_MACHINE_NPM_PACKAGE_NAME } from \"../../constants/SLICE_MACHINE_NPM_PACKAGE_NAME\";\nimport { VERSION_KIND } from \"../../constants/VERSION_KIND\";\n\nimport { BaseManager } from \"../BaseManager\";\n\nimport { Version } from \"./types\";\n\nconst detectVersionBumpKind = (\n\tto: string,\n\tfrom?: string,\n): typeof VERSION_KIND[keyof typeof VERSION_KIND] | undefined => {\n\tif (!from) {\n\t\treturn VERSION_KIND.FIRST;\n\t}\n\n\tif (semver.eq(to, from)) {\n\t\treturn undefined;\n\t} else if (semver.satisfies(to, `~${from}`)) {\n\t\treturn VERSION_KIND.PATCH;\n\t} else if (semver.satisfies(to, `^${from}`)) {\n\t\treturn VERSION_KIND.MINOR;\n\t} else {\n\t\treturn VERSION_KIND.MAJOR;\n\t}\n};\n\ntype SliceMachineManagerGetReleaseNotesForVersionArgs = {\n\tversion: string;\n};\n\nexport class VersionsManager extends BaseManager {\n\t/**\n\t * Record of version numbers mapped to their GitHub release metadata.\n\t */\n\tgitHubSliceMachineReleaseMetadataCache: Record<\n\t\tstring,\n\t\tGitHubReleaseMetadata | undefined\n\t> = {};\n\n\tasync getRunningSliceMachineVersion(): Promise<string> {\n\t\tconst sliceMachineDir = await this.project.locateSliceMachineUIDir();\n\n\t\tconst sliceMachinePackageJSONContents = await fs.readFile(\n\t\t\tpath.join(sliceMachineDir, \"package.json\"),\n\t\t\t\"utf8\",\n\t\t);\n\n\t\tlet sliceMachinePackageJSON: unknown;\n\t\ttry {\n\t\t\tsliceMachinePackageJSON = JSON.parse(sliceMachinePackageJSONContents);\n\t\t} catch {\n\t\t\t// noop\n\t\t}\n\n\t\tconst { value, error } = decodePackageJSON(sliceMachinePackageJSON);\n\n\t\tif (error) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid ${SLICE_MACHINE_NPM_PACKAGE_NAME} \\`package.json\\` file. ${error.errors.join(\n\t\t\t\t\t\", \",\n\t\t\t\t)}`,\n\t\t\t);\n\t\t}\n\n\t\treturn value.version;\n\t}\n\n\tasync getAllStableSliceMachineVersions(): Promise<string[]> {\n\t\tconst versions = await fetchNPMPackageVersions({\n\t\t\tpackageName: SLICE_MACHINE_NPM_PACKAGE_NAME,\n\t\t});\n\n\t\tconst filteredVersions = versions.filter((version) => {\n\t\t\t// Exclude tagged versions (e.g. `1.0.0-alpha.0`).\n\t\t\t// Exclude versions < 0.1.0 (e.g. `0.0.1`).\n\t\t\treturn (\n\t\t\t\t/^[1-9]\\d*\\.\\d+\\.\\d+$/.test(version) ||\n\t\t\t\t/^\\d+\\.[1-9]\\d*\\.\\d+$/.test(version)\n\t\t\t);\n\t\t});\n\n\t\treturn semver.rsort(filteredVersions);\n\t}\n\n\tasync getAllStableSliceMachineVersionsWithKind(): Promise<Version[]> {\n\t\tconst versions = await this.getAllStableSliceMachineVersions();\n\n\t\treturn versions.map((version, i) => {\n\t\t\tconst previousVersion = versions[i + 1];\n\n\t\t\treturn {\n\t\t\t\tversion,\n\t\t\t\tkind: detectVersionBumpKind(version, previousVersion),\n\t\t\t};\n\t\t});\n\t}\n\n\tasync getLatestNonBreakingSliceMachineVersion(): Promise<string | undefined> {\n\t\tconst versions = await this.getAllStableSliceMachineVersions();\n\t\tconst currentVersion = await this.getRunningSliceMachineVersion();\n\n\t\treturn semver.maxSatisfying(versions, `^${currentVersion}`) ?? undefined;\n\t}\n\n\tasync checkIsUpdateAvailable(): Promise<boolean> {\n\t\tconst versions = await this.getAllStableSliceMachineVersions();\n\t\tconst currentVersion = await this.getRunningSliceMachineVersion();\n\n\t\treturn semver.gt(versions[0], currentVersion);\n\t}\n\n\tasync getSliceMachineReleaseNotesForVersion(\n\t\targs: SliceMachineManagerGetReleaseNotesForVersionArgs,\n\t): Promise<string | undefined> {\n\t\treturn await fetchGitHubReleaseBodyForRelease({\n\t\t\trepositoryOwner: SLICE_MACHINE_GITHUB_REPOSITORY_ORGANIZATION,\n\t\t\trepositoryName: SLICE_MACHINE_GITHUB_REPOSITORY_NAME,\n\t\t\tpackageName: SLICE_MACHINE_GITHUB_PACKAGE_NAME,\n\t\t\tversion: args.version,\n\t\t\tcache: this.gitHubSliceMachineReleaseMetadataCache,\n\t\t});\n\t}\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,wBAAwB,CAC7B,IACA,SAC+D;AAC/D,MAAI,CAAC,MAAM;AACV,WAAO,aAAa;AAAA,EACpB;AAED,MAAI,OAAO,GAAG,IAAI,IAAI,GAAG;AACjB,WAAA;AAAA,EAAA,WACG,OAAO,UAAU,IAAI,IAAI,MAAM,GAAG;AAC5C,WAAO,aAAa;AAAA,EAAA,WACV,OAAO,UAAU,IAAI,IAAI,MAAM,GAAG;AAC5C,WAAO,aAAa;AAAA,EAAA,OACd;AACN,WAAO,aAAa;AAAA,EACpB;AACF;AAMM,MAAO,wBAAwB,YAAW;AAAA,EAA1C;AAAA;AAIL;AAAA;AAAA;AAAA,kEAGI,CAAA;AAAA;AAAA,EAEJ,MAAM,gCAA6B;AAClC,UAAM,kBAAkB,MAAM,KAAK,QAAQ,wBAAuB;AAE5D,UAAA,kCAAkC,MAAM,GAAG,SAChD,KAAK,KAAK,iBAAiB,cAAc,GACzC,MAAM;AAGH,QAAA;AACA,QAAA;AACuB,gCAAA,KAAK,MAAM,+BAA+B;AAAA,IAAA,QACnE;AAAA,IAED;AAED,UAAM,EAAE,OAAO,MAAK,IAAK,kBAAkB,uBAAuB;AAElE,QAAI,OAAO;AACJ,YAAA,IAAI,MACT,WAAW,yDAAyD,MAAM,OAAO,KAChF,IAAI,GACF;AAAA,IAEJ;AAED,WAAO,MAAM;AAAA,EACd;AAAA,EAEA,MAAM,mCAAgC;AAC/B,UAAA,WAAW,MAAM,wBAAwB;AAAA,MAC9C,aAAa;AAAA,IAAA,CACb;AAED,UAAM,mBAAmB,SAAS,OAAO,CAAC,YAAW;AAGpD,aACC,uBAAuB,KAAK,OAAO,KACnC,uBAAuB,KAAK,OAAO;AAAA,IAAA,CAEpC;AAEM,WAAA,OAAO,MAAM,gBAAgB;AAAA,EACrC;AAAA,EAEA,MAAM,2CAAwC;AACvC,UAAA,WAAW,MAAM,KAAK;AAE5B,WAAO,SAAS,IAAI,CAAC,SAAS,MAAK;AAC5B,YAAA,kBAAkB,SAAS,IAAI,CAAC;AAE/B,aAAA;AAAA,QACN;AAAA,QACA,MAAM,sBAAsB,SAAS,eAAe;AAAA,MAAA;AAAA,KAErD;AAAA,EACF;AAAA,EAEA,MAAM,0CAAuC;AACtC,UAAA,WAAW,MAAM,KAAK;AACtB,UAAA,iBAAiB,MAAM,KAAK;AAElC,WAAO,OAAO,cAAc,UAAU,IAAI,gBAAgB,KAAK;AAAA,EAChE;AAAA,EAEA,MAAM,yBAAsB;AACrB,UAAA,WAAW,MAAM,KAAK;AACtB,UAAA,iBAAiB,MAAM,KAAK;AAElC,WAAO,OAAO,GAAG,SAAS,CAAC,GAAG,cAAc;AAAA,EAC7C;AAAA,EAEA,MAAM,sCACL,MAAsD;AAEtD,WAAO,MAAM,iCAAiC;AAAA,MAC7C,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,IAAA,CACZ;AAAA,EACF;AACA;"}
@@ -1,5 +1,5 @@
1
1
  import { VERSION_KIND } from "../../constants/VERSION_KIND";
2
2
  export type Version = {
3
3
  version: string;
4
- kind: typeof VERSION_KIND[keyof typeof VERSION_KIND];
4
+ kind: typeof VERSION_KIND[keyof typeof VERSION_KIND] | undefined;
5
5
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slicemachine/manager",
3
- "version": "0.1.1-dev-plugins.11",
3
+ "version": "0.1.1-dev-plugins.12",
4
4
  "description": "Manage all aspects of a Slice Machine project.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -52,7 +52,8 @@
52
52
  "lint": "eslint --ext .js,.ts .",
53
53
  "prepare": "npm run build",
54
54
  "size": "size-limit",
55
- "test": "npm run lint && npm run unit && npm run build && npm run size",
55
+ "test": "npm run lint && npm run types && npm run unit && npm run build && npm run size",
56
+ "types": "tsc --noEmit",
56
57
  "unit": "vitest run --coverage",
57
58
  "unit:watch": "vitest watch",
58
59
  "depcheck": "depcheck --config=.depcheckrc"
@@ -60,7 +61,7 @@
60
61
  "dependencies": {
61
62
  "@prismicio/custom-types-client": "^1.0.2",
62
63
  "@prismicio/types-internal": "^1.5.3",
63
- "@slicemachine/plugin-kit": "0.1.8-dev-plugins.11",
64
+ "@slicemachine/plugin-kit": "0.1.8-dev-plugins.12",
64
65
  "@wooorm/starry-night": "^1.4.2",
65
66
  "analytics-node": "^6.2.0",
66
67
  "cookie": "^0.5.0",
@@ -87,8 +88,9 @@
87
88
  "devDependencies": {
88
89
  "@prismicio/mock": "^0.2.0",
89
90
  "@size-limit/preset-small-lib": "^8.1.0",
90
- "@types/analytics-node": "^3.1.9",
91
+ "@types/analytics-node": "^3.1.10",
91
92
  "@types/cookie": "^0.5.1",
93
+ "@types/express": "^4.17.17",
92
94
  "@types/semver": "^7.3.13",
93
95
  "@typescript-eslint/eslint-plugin": "~5.46.1",
94
96
  "@typescript-eslint/parser": "^5.46.1",
@@ -124,5 +126,5 @@
124
126
  "publishConfig": {
125
127
  "access": "public"
126
128
  },
127
- "gitHead": "033da5acbcbf93792fa478b4d83386034a0f4f09"
129
+ "gitHead": "913882c4079ffcab3a72938b4be902470c1e3c32"
128
130
  }
@@ -1,6 +1,6 @@
1
1
  import { APPLICATION_MODE } from "./APPLICATION_MODE";
2
2
 
3
- type APIEndpoints = {
3
+ export type APIEndpoints = {
4
4
  PrismicWroom: string;
5
5
  PrismicAuthentication: string;
6
6
  PrismicModels: string;
package/src/errors.ts CHANGED
@@ -1,53 +1,6 @@
1
- // const Errors = {
2
- // 1000: {
3
- // message: "Could not refresh token",
4
- // description:
5
- // "You are not logged in. Log in before refreshing your authentication token.",
6
- // },
7
- // 1001: {
8
- // message: "Failed to refresh authentication token",
9
- // description:
10
- // "The Prismic Authentication service returned an invalid response.",
11
- // },
12
- // 1002: {
13
- // message: "Failed to refresh authentication token",
14
- // description:
15
- // "You are not logged in. Log in before attempting to get your authentication token.",
16
- // },
17
- // // 1000: {
18
- // // message: "Unauthenticated",
19
- // // description:
20
- // // "Unable to access the Prismic Custom Types API. Log in to fix this issue.",
21
- // // },
22
- // // 1001: {
23
- // // message: "Unauthorized",
24
- // // description:
25
- // // "Unable to access the Prismic Custom Types API. Grant the user access to the repository to fix this issue.",
26
- // // },
27
- // } as const;
28
- // type Errors = typeof Errors;
29
-
30
1
  import { HookError } from "@slicemachine/plugin-kit";
31
2
 
32
- // const InternalErrorCodes = {
33
- // Unauthorized: "Unauthorized",
34
- // Unauthenticated: "Unauthenticated",
35
- // InternalServerError: "InternalServerError",
36
- // } as const;
37
- // type InternalErrorCodes =
38
- // typeof InternalErrorCodes[keyof typeof InternalErrorCodes];
39
-
40
- // type InternalErrorCode =
41
- // | typeof InternalError.Unauthorized
42
- // | typeof InternalError.Unauthenticated
43
- // | typeof InternalError.InternalServerError;
44
-
45
- // type InternalErrorArgs = {
46
- // message?: string;
47
- // cause?: Error;
48
- // };
49
-
50
- export abstract class SliceMachineError extends Error {
3
+ export class SliceMachineError extends Error {
51
4
  _sliceMachineError = true;
52
5
  name = "SliceMachineError";
53
6
  }
@@ -118,29 +71,3 @@ export const isUnexpectedDataError = (
118
71
  export const isInternalError = (error: unknown): error is InternalError => {
119
72
  return isSliceMachineError(error) && error.name === InternalError.name;
120
73
  };
121
-
122
- // export class InternalError<TCode extends InternalErrorCode> extends Error {
123
- // static Unauthorized = "Unauthorized" as const;
124
- // static Unauthenticated = "Unauthenticated" as const;
125
- // static InternalServerError = "InternalServerError" as const;
126
- //
127
- // code: TCode;
128
- // cause?: Error;
129
- //
130
- // constructor(code: TCode, args: InternalErrorArgs = {}) {
131
- // super(args.message);
132
- //
133
- // this.code = code;
134
- // this.cause = args.cause;
135
- //
136
- // // const error = Errors[code];
137
- //
138
- // // this.message = error.message as TMessage;
139
- //
140
- // // if ("description" in error) {
141
- // // this.description = error.description as TDescription;
142
- // // } else {
143
- // // this.description = undefined as TDescription;
144
- // // }
145
- // }
146
- // }
@@ -0,0 +1,18 @@
1
+ import * as t from "io-ts";
2
+
3
+ import { decode, DecodeReturnType } from "./decode";
4
+
5
+ /**
6
+ * A minimally defined codec for package.json files. Only data needed for
7
+ * version detection is defined.
8
+ */
9
+ const PackageJSONCodec = t.type({
10
+ version: t.string,
11
+ });
12
+ type PackageJSON = t.TypeOf<typeof PackageJSONCodec>;
13
+
14
+ export const decodePackageJSON = (
15
+ input: unknown,
16
+ ): DecodeReturnType<PackageJSON, PackageJSON, unknown> => {
17
+ return decode(PackageJSONCodec, input);
18
+ };
@@ -24,25 +24,21 @@ export const locateFileUpward = async (
24
24
 
25
25
  const filePaths = castArray(filePathOrPaths);
26
26
 
27
- try {
28
- for (const filePath of filePaths) {
29
- const resolvedFilePath = path.resolve(startDir, filePath);
27
+ for (const filePath of filePaths) {
28
+ const resolvedFilePath = path.resolve(startDir, filePath);
30
29
 
31
- try {
32
- await fs.access(resolvedFilePath);
30
+ try {
31
+ await fs.access(resolvedFilePath);
33
32
 
34
- return resolvedFilePath;
35
- } catch {
36
- continue;
37
- }
33
+ return resolvedFilePath;
34
+ } catch {
35
+ continue;
38
36
  }
39
- } catch {
40
- // noop
41
37
  }
42
38
 
43
39
  if (startDir === stopDir) {
44
40
  const formattedFilePaths = filePaths
45
- .map((filePath) => `\`${filePath}\``)
41
+ .map((filePath) => "`" + filePath + "`")
46
42
  .join(" or ");
47
43
 
48
44
  throw new Error(
@@ -19,6 +19,8 @@ import {
19
19
  } from "../auth/PrismicAuthManager";
20
20
  import { createPrismicAuthManager } from "../auth/createPrismicAuthManager";
21
21
 
22
+ import { API_ENDPOINTS, APIEndpoints } from "../constants/API_ENDPOINTS";
23
+
22
24
  import { UserManager } from "./user/UserManager";
23
25
  import { PrismicRepositoryManager } from "./prismicRepository/PrismicRepositoryManager";
24
26
 
@@ -153,6 +155,10 @@ export class SliceMachineManager {
153
155
  return this._prismicAuthManager;
154
156
  }
155
157
 
158
+ getAPIEndpoints(): APIEndpoints {
159
+ return API_ENDPOINTS;
160
+ }
161
+
156
162
  // TODO: Remove this global-state method. It is expensive and a
157
163
  // potential source of bugs due to data inconsistency. SM UI relies on
158
164
  // it heavily, so removal will require significant effort.
@@ -2,10 +2,10 @@ import { SliceMachineManager } from "./SliceMachineManager";
2
2
 
3
3
  type CreateSliceMachineManagerArgs = ConstructorParameters<
4
4
  typeof SliceMachineManager
5
- >[0];
5
+ >;
6
6
 
7
7
  export const createSliceMachineManager = (
8
- args?: CreateSliceMachineManagerArgs,
8
+ ...args: CreateSliceMachineManagerArgs
9
9
  ): SliceMachineManager => {
10
- return new SliceMachineManager(args);
10
+ return new SliceMachineManager(...args);
11
11
  };
@@ -104,7 +104,7 @@ type SliceMachineManagerReadSliceMocksArgs = {
104
104
 
105
105
  type SliceMachineManagerReadSliceMocksReturnType = {
106
106
  mocks?: SharedSliceContent[];
107
- errors: HookError[];
107
+ errors: (DecodeError | HookError)[];
108
108
  };
109
109
 
110
110
  type SliceMachineManagerReadSliceMocksConfigArgs = {
@@ -467,19 +467,36 @@ export class SlicesManager extends BaseManager {
467
467
  assetID: `mocks.json`,
468
468
  },
469
469
  );
470
- const data = hookResult.data[0]?.data;
471
-
472
- // TODO: Validate the returned mocks.
470
+ const { data, errors } = decodeHookResult(
471
+ t.type({
472
+ data: t.array(SharedSliceContent),
473
+ }),
474
+ {
475
+ ...hookResult,
476
+ // Convert the asset data from a Buffer to JSON
477
+ // to prepare it for validation.
478
+ data: hookResult.data.map((result) => {
479
+ try {
480
+ return {
481
+ ...result,
482
+ data: JSON.parse(result.data.toString()),
483
+ };
484
+ } catch {
485
+ return result;
486
+ }
487
+ }),
488
+ },
489
+ );
473
490
 
474
491
  if (data) {
475
492
  return {
476
- mocks: JSON.parse(data.toString()),
477
- errors: hookResult.errors,
493
+ mocks: data[0]?.data,
494
+ errors,
478
495
  };
479
496
  } else {
480
497
  return {
481
498
  mocks: [],
482
- errors: hookResult.errors,
499
+ errors,
483
500
  };
484
501
  }
485
502
  }
@@ -56,6 +56,12 @@ export class TelemetryManager extends BaseManager {
56
56
  flushAt: 1,
57
57
  // TODO: Verify that this actually does not send data to Segment when false.
58
58
  enable: this._enabled,
59
+ errorHandler: () => {
60
+ // noop - We don't care if the tracking event
61
+ // failed. Some users or networks intentionally
62
+ // block Segment, so we can't block the app if
63
+ // a tracking event is unsuccessful.
64
+ },
59
65
  });
60
66
  this._anonymousID = randomUUID();
61
67
  }
@@ -1,6 +1,18 @@
1
+ import { SliceMachineError } from "../../errors";
1
2
  import { BaseManager } from "../BaseManager";
3
+ import { SliceMachineManager } from "../SliceMachineManager";
2
4
 
3
5
  export class UserManager extends BaseManager {
6
+ constructor(sliceMachineManager: SliceMachineManager) {
7
+ super(sliceMachineManager);
8
+
9
+ if (!sliceMachineManager.getPrismicAuthManager()) {
10
+ throw new SliceMachineError(
11
+ "SliceMachineManager._prismicAuthManager must be set with a PrismicAuthManager instance before instantiating UserManager.",
12
+ );
13
+ }
14
+ }
15
+
4
16
  login = this.prismicAuthManager.login.bind(this.prismicAuthManager);
5
17
  getLoginSessionInfo = this.prismicAuthManager.getLoginSessionInfo.bind(
6
18
  this.prismicAuthManager,
@@ -2,6 +2,7 @@ import * as fs from "node:fs/promises";
2
2
  import * as path from "node:path";
3
3
  import semver from "semver";
4
4
 
5
+ import { decodePackageJSON } from "../../lib/decodePackageJSON";
5
6
  import {
6
7
  fetchGitHubReleaseBodyForRelease,
7
8
  GitHubReleaseMetadata,
@@ -21,12 +22,14 @@ import { Version } from "./types";
21
22
  const detectVersionBumpKind = (
22
23
  to: string,
23
24
  from?: string,
24
- ): typeof VERSION_KIND[keyof typeof VERSION_KIND] => {
25
+ ): typeof VERSION_KIND[keyof typeof VERSION_KIND] | undefined => {
25
26
  if (!from) {
26
27
  return VERSION_KIND.FIRST;
27
28
  }
28
29
 
29
- if (semver.satisfies(to, `~${from}`)) {
30
+ if (semver.eq(to, from)) {
31
+ return undefined;
32
+ } else if (semver.satisfies(to, `~${from}`)) {
30
33
  return VERSION_KIND.PATCH;
31
34
  } else if (semver.satisfies(to, `^${from}`)) {
32
35
  return VERSION_KIND.MINOR;
@@ -56,11 +59,24 @@ export class VersionsManager extends BaseManager {
56
59
  "utf8",
57
60
  );
58
61
 
59
- // TODO: Validate the contents? This code currently assumes a
60
- // well-formed document.
61
- const json = JSON.parse(sliceMachinePackageJSONContents);
62
+ let sliceMachinePackageJSON: unknown;
63
+ try {
64
+ sliceMachinePackageJSON = JSON.parse(sliceMachinePackageJSONContents);
65
+ } catch {
66
+ // noop
67
+ }
62
68
 
63
- return json.version;
69
+ const { value, error } = decodePackageJSON(sliceMachinePackageJSON);
70
+
71
+ if (error) {
72
+ throw new Error(
73
+ `Invalid ${SLICE_MACHINE_NPM_PACKAGE_NAME} \`package.json\` file. ${error.errors.join(
74
+ ", ",
75
+ )}`,
76
+ );
77
+ }
78
+
79
+ return value.version;
64
80
  }
65
81
 
66
82
  async getAllStableSliceMachineVersions(): Promise<string[]> {
@@ -2,5 +2,5 @@ import { VERSION_KIND } from "../../constants/VERSION_KIND";
2
2
 
3
3
  export type Version = {
4
4
  version: string;
5
- kind: typeof VERSION_KIND[keyof typeof VERSION_KIND];
5
+ kind: typeof VERSION_KIND[keyof typeof VERSION_KIND] | undefined;
6
6
  };