@tryghost/errors 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/GhostError.js CHANGED
@@ -23,7 +23,7 @@ __export(GhostError_exports, {
23
23
  GhostError: () => GhostError
24
24
  });
25
25
  module.exports = __toCommonJS(GhostError_exports);
26
- var import_uuid = require("uuid");
26
+ var import_crypto = require("crypto");
27
27
  var import_wrap_stack = require("./wrap-stack");
28
28
  class GhostError extends Error {
29
29
  constructor(options = {}) {
@@ -44,7 +44,7 @@ class GhostError extends Error {
44
44
  this.errorType = "InternalServerError";
45
45
  this.level = "normal";
46
46
  this.message = "The server has encountered an error.";
47
- this.id = (0, import_uuid.v1)();
47
+ this.id = (0, import_crypto.randomUUID)();
48
48
  this.id = options.id || this.id;
49
49
  this.statusCode = options.statusCode || this.statusCode;
50
50
  this.level = options.level || this.level;
package/cjs/utils.js CHANGED
@@ -34,9 +34,28 @@ __export(utils_exports, {
34
34
  serialize: () => serialize
35
35
  });
36
36
  module.exports = __toCommonJS(utils_exports);
37
- var import_utils_copy = __toESM(require("@stdlib/utils-copy"));
38
37
  var import_GhostError = require("./GhostError");
39
38
  var errors = __toESM(require("./errors"));
39
+ function deepCloneValue(value) {
40
+ if (value === null || typeof value !== "object") {
41
+ return value;
42
+ }
43
+ if (value instanceof Error) {
44
+ const clone2 = Object.create(Object.getPrototypeOf(value));
45
+ for (const key of Object.getOwnPropertyNames(value)) {
46
+ clone2[key] = deepCloneValue(value[key]);
47
+ }
48
+ return clone2;
49
+ }
50
+ if (Array.isArray(value)) {
51
+ return value.map(deepCloneValue);
52
+ }
53
+ const clone = {};
54
+ for (const key of Object.keys(value)) {
55
+ clone[key] = deepCloneValue(value[key]);
56
+ }
57
+ return clone;
58
+ }
40
59
  const errorsWithBase = { ...errors, GhostError: import_GhostError.GhostError };
41
60
  const _private = {
42
61
  serialize(err) {
@@ -182,7 +201,7 @@ function prepareStackForUser(error) {
182
201
  if ("context" in error && error.context) {
183
202
  stackbits.splice(1, 0, `${error.context}`);
184
203
  }
185
- const errorClone = (0, import_utils_copy.default)(error);
204
+ const errorClone = deepCloneValue(error);
186
205
  errorClone.stack = stackbits.join("\n");
187
206
  return errorClone;
188
207
  }
package/es/GhostError.js CHANGED
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { v1 as uuidv1 } from "uuid";
4
+ import { randomUUID } from "crypto";
5
5
  import { wrapStack } from "./wrap-stack";
6
6
  class GhostError extends Error {
7
7
  constructor(options = {}) {
@@ -22,7 +22,7 @@ class GhostError extends Error {
22
22
  this.errorType = "InternalServerError";
23
23
  this.level = "normal";
24
24
  this.message = "The server has encountered an error.";
25
- this.id = uuidv1();
25
+ this.id = randomUUID();
26
26
  this.id = options.id || this.id;
27
27
  this.statusCode = options.statusCode || this.statusCode;
28
28
  this.level = options.level || this.level;
package/es/utils.js CHANGED
@@ -1,6 +1,25 @@
1
- import deepCopy from "@stdlib/utils-copy";
2
1
  import { GhostError } from "./GhostError";
3
2
  import * as errors from "./errors";
3
+ function deepCloneValue(value) {
4
+ if (value === null || typeof value !== "object") {
5
+ return value;
6
+ }
7
+ if (value instanceof Error) {
8
+ const clone2 = Object.create(Object.getPrototypeOf(value));
9
+ for (const key of Object.getOwnPropertyNames(value)) {
10
+ clone2[key] = deepCloneValue(value[key]);
11
+ }
12
+ return clone2;
13
+ }
14
+ if (Array.isArray(value)) {
15
+ return value.map(deepCloneValue);
16
+ }
17
+ const clone = {};
18
+ for (const key of Object.keys(value)) {
19
+ clone[key] = deepCloneValue(value[key]);
20
+ }
21
+ return clone;
22
+ }
4
23
  const errorsWithBase = { ...errors, GhostError };
5
24
  const _private = {
6
25
  serialize(err) {
@@ -146,7 +165,7 @@ function prepareStackForUser(error) {
146
165
  if ("context" in error && error.context) {
147
166
  stackbits.splice(1, 0, `${error.context}`);
148
167
  }
149
- const errorClone = deepCopy(error);
168
+ const errorClone = deepCloneValue(error);
150
169
  errorClone.stack = stackbits.join("\n");
151
170
  return errorClone;
152
171
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tryghost/errors",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/TryGhost/framework.git",
@@ -21,7 +21,7 @@
21
21
  "build:cjs": "esbuild src/*.ts --target=es2020 --outdir=cjs --format=cjs",
22
22
  "build:es": "esbuild src/*.ts --target=es2020 --outdir=es --format=esm",
23
23
  "build:types": "tsc --emitDeclarationOnly --declaration --declarationMap --outDir types",
24
- "test": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' NODE_ENV=testing c8 --check-coverage --100 --all -n src --reporter text --reporter cobertura mocha -r ts-node/register './test/**/*.test.ts'",
24
+ "test": "NODE_ENV=testing vitest run --coverage",
25
25
  "lint": "eslint . --ext .js --cache",
26
26
  "posttest": "yarn lint"
27
27
  },
@@ -36,17 +36,10 @@
36
36
  },
37
37
  "devDependencies": {
38
38
  "@types/lodash": "4.17.24",
39
- "@types/mocha": "10.0.10",
40
- "@types/uuid": "11.0.0",
41
- "c8": "11.0.0",
42
39
  "esbuild": "0.27.3",
43
40
  "lodash": "4.17.23",
44
- "mocha": "11.7.5",
45
41
  "ts-node": "10.9.2",
46
42
  "typescript": "5.9.3"
47
43
  },
48
- "dependencies": {
49
- "@stdlib/utils-copy": "0.2.3",
50
- "uuid": "13.0.0"
51
- }
44
+ "dependencies": {}
52
45
  }
package/src/GhostError.ts CHANGED
@@ -1,4 +1,4 @@
1
- import {v1 as uuidv1} from 'uuid';
1
+ import {randomUUID} from 'crypto';
2
2
  import {wrapStack} from './wrap-stack';
3
3
 
4
4
  export interface GhostErrorOptions {
@@ -42,7 +42,7 @@ export class GhostError extends Error {
42
42
  this.errorType = 'InternalServerError';
43
43
  this.level = 'normal';
44
44
  this.message = 'The server has encountered an error.';
45
- this.id = uuidv1();
45
+ this.id = randomUUID();
46
46
 
47
47
  /**
48
48
  * custom overrides
package/src/utils.ts CHANGED
@@ -1,10 +1,33 @@
1
- import deepCopy from '@stdlib/utils-copy';
2
1
  import {GhostError} from './GhostError';
3
2
  import * as errors from './errors';
4
3
 
5
4
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
5
  type AnyObject = Record<string, any>
7
6
 
7
+ // structuredClone doesn't preserve custom properties on Error subclasses
8
+ // (see https://github.com/ungap/structured-clone/issues/12)
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ function deepCloneValue(value: any): any {
11
+ if (value === null || typeof value !== 'object') {
12
+ return value;
13
+ }
14
+ if (value instanceof Error) {
15
+ const clone = Object.create(Object.getPrototypeOf(value));
16
+ for (const key of Object.getOwnPropertyNames(value)) {
17
+ clone[key] = deepCloneValue((value as AnyObject)[key]);
18
+ }
19
+ return clone;
20
+ }
21
+ if (Array.isArray(value)) {
22
+ return value.map(deepCloneValue);
23
+ }
24
+ const clone: AnyObject = {};
25
+ for (const key of Object.keys(value)) {
26
+ clone[key] = deepCloneValue(value[key]);
27
+ }
28
+ return clone;
29
+ }
30
+
8
31
  const errorsWithBase: Record<string, typeof GhostError> = {...errors, GhostError};
9
32
 
10
33
  const _private = {
@@ -205,11 +228,7 @@ export function prepareStackForUser(error: Error): Error {
205
228
  stackbits.splice(1, 0, `${error.context}`);
206
229
  }
207
230
 
208
- // @NOTE: would be a good idea to swap out the cloning implementation with native
209
- // `structuredClone` one once we use Node v17 or higher. Before making an
210
- // upgrade make sure structuredClone does a full copy of all properties
211
- // present on a custom error (see issue: https://github.com/ungap/structured-clone/issues/12)
212
- const errorClone = deepCopy(error);
231
+ const errorClone = deepCloneValue(error);
213
232
  errorClone.stack = stackbits.join('\n');
214
233
  return errorClone;
215
234
  };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAIxC,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AA+HpC;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;IAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAA;CAAC,aAiBjF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,SAAS,GAAG,SAAS,CAU7D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAA;AAClE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAAA;AAiCxD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,KAAK,WAkBtC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAIxC,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAuJpC;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;IAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAA;CAAC,aAiBjF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,SAAS,GAAG,SAAS,CAU7D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAAA;AAClE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAAA;AA6BxD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,KAAK,WAkBtC"}