@pixieset/versioning-js 1.0.13
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/LICENSE +1 -0
- package/README.md +87 -0
- package/dist/ApiVersion.d.ts +12 -0
- package/dist/ApiVersion.js +98 -0
- package/dist/Error/VersioningError.d.ts +8 -0
- package/dist/Error/VersioningError.js +19 -0
- package/dist/axios_helpers.d.ts +14 -0
- package/dist/axios_helpers.js +102 -0
- package/dist/capacitor_helpers.d.ts +16 -0
- package/dist/capacitor_helpers.js +90 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.js +15 -0
- package/dist/helpers.d.ts +4 -0
- package/dist/helpers.js +16 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +44 -0
- package/dist/sentry.d.ts +9 -0
- package/dist/sentry.js +14 -0
- package/package.json +54 -0
package/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Unlicensed
|
package/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# Pixieset Laravel versioning
|
2
|
+
This library is meant to augment the Laravel versioning approach created for Studio Manager. This repository contains
|
3
|
+
the front-end code for this project, and should be installed in conjunction with the backend work.
|
4
|
+
|
5
|
+
The frontend part contains helpers that can be used to manage the versioning of resources in a frontend application, specifically, the handling of when there are version inconsistencies.
|
6
|
+
|
7
|
+
|
8
|
+
## Contents
|
9
|
+
- [Pixieset Laravel versioning](#pixieset-laravel-versioning)
|
10
|
+
- [Contents](#contents)
|
11
|
+
- [Installation](#installation)
|
12
|
+
- [Usage](#usage)
|
13
|
+
- [Bundle development](#bundle-development)
|
14
|
+
- [Prerequisites](#prerequisites)
|
15
|
+
- [Installation](#installation-1)
|
16
|
+
- [Building](#building)
|
17
|
+
- [Pushing changes](#pushing-changes)
|
18
|
+
- [Footnotes](#footnotes)
|
19
|
+
---
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
|
23
|
+
**Prerequisites**:
|
24
|
+
|
25
|
+
Currently, this project supports Axios, Laravel, and Capacitor. You must also have a working Sentry integration in your front-end code already, and you must have installed the backend version checking code.
|
26
|
+
|
27
|
+
**Installation**:
|
28
|
+
|
29
|
+
The built front-end distribution code for this project is currently publicly available on packagist. Update your `package.json` file to include the following:
|
30
|
+
|
31
|
+
```json
|
32
|
+
{
|
33
|
+
"dependencies": {
|
34
|
+
"@pixieset/versioning-js": "^1.0"
|
35
|
+
}
|
36
|
+
}
|
37
|
+
```
|
38
|
+
|
39
|
+
Then run `yarn install` to install the package.
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
For information on versioning usage, see [the Pixieset internal documentation](https://www.notion.so/pixieset/Studio-Manager-Resource-Versioning-WIP-d702c157a24e496e92f869eca2015c1b).
|
44
|
+
|
45
|
+
## Bundle development
|
46
|
+
|
47
|
+
This section is for developers who want to make changes to the bundle. It is assumed that you have a Laravel application that you are using to test the changes.
|
48
|
+
|
49
|
+
This package uses a Makefile to assist in building the package. See that file for the commands available, or run `make help` to see a list of available commands in that subfolder.
|
50
|
+
|
51
|
+
### Prerequisites
|
52
|
+
To build the frontend package, you will need to have the following installed:
|
53
|
+
- nodejs, version 18 or higher, with yarn globally.
|
54
|
+
- Follow the directions [here](https://classic.yarnpkg.com/lang/en/docs/cli/version/), as well, if you intend to commit.
|
55
|
+
|
56
|
+
### Installation
|
57
|
+
To make the frontend available locally, you can use the following steps:
|
58
|
+
|
59
|
+
1. Clone this repository into a directory of your Laravel application (if you haven't already done so). Preferably one that will not pollute your primary git source tree. We're going to use symlinks to connect it in a moment.
|
60
|
+
2. In the `versioning-js` portion of the package, invoke `yarn link`. This will make the package available for local linking and modification.
|
61
|
+
3. In your service provider where you are using the package (e.g. Studio Manager), invoke `yarn link @pixieset/versioning-js`. That will cause `yarn` to symlink the two, so you can make changes locally, and see them every time you run `make build`.
|
62
|
+
4. Run your local service provider front end `*-watch` task, to start hot-rebuilding your code based on file changes.
|
63
|
+
5. When done, run `yarn unlink @pixieset/versioning-js` within the service provider, to stop using linked code. Commit and tag your changes.
|
64
|
+
|
65
|
+
|
66
|
+
### Building
|
67
|
+
|
68
|
+
The frontend package contains build artifacts in the `dist` subfolder, which are compiled typescript files. These files are what you should be importing into your Vue components. Any changes you make to the typescript files in the `src` directory should be compiled into the `dist` directory when you run `make build`.
|
69
|
+
|
70
|
+
### Pushing changes
|
71
|
+
|
72
|
+
This project uses the [yarn version](https://classic.yarnpkg.com/lang/en/docs/cli/version/) tooling to publish changes. You should have set up your local environment as specified in the prerequisites.
|
73
|
+
|
74
|
+
First, set up your pull request, and confirm the changes you'd like to make. Use `yarn link` as described above, to ensure the changes actually work.
|
75
|
+
|
76
|
+
Once the pull request is merged, use `yarn version` as per the yarn documentation to create and publish a new front-end version. This should:
|
77
|
+
|
78
|
+
1. Create a new version number in package.json
|
79
|
+
2. Create a new git tag, with the same value.
|
80
|
+
|
81
|
+
Push the results of this, using `git push --tags`. This will trigger the pipeline to create a new build version automatically, and deploy it to NPM for installation.
|
82
|
+
|
83
|
+
Remember to unlink yarn before you try to install it.
|
84
|
+
|
85
|
+
## Footnotes
|
86
|
+
|
87
|
+
- For more information on the technical proposal, see [here](https://www.notion.so/pixieset/Technical-Proposal-SM-API-resource-versioning-41be2336e8f74ce5b1bdbaa04aa04a62?pm=c).
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import VersioningError from "./Error/VersioningError";
|
2
|
+
import { VersioningHeaders } from "./types";
|
3
|
+
export default class APIVersion {
|
4
|
+
requestedVersion: number;
|
5
|
+
version: number;
|
6
|
+
deprecation: Date | null;
|
7
|
+
sunsetDate: Date | null;
|
8
|
+
availableVersions: number[];
|
9
|
+
errors: VersioningError[];
|
10
|
+
constructor(requestedVersion: number | null, version: number, deprecation: Date | null, sunset: Date | null, availableVersions: number[], errors: VersioningError[]);
|
11
|
+
static fromHeaders(headers: VersioningHeaders): APIVersion;
|
12
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const VersioningError_1 = __importDefault(require("./Error/VersioningError"));
|
7
|
+
const constants_1 = require("./constants");
|
8
|
+
function parseVersionInfoValue(value) {
|
9
|
+
const parts = value.split('; ');
|
10
|
+
const responseVersion = parseInt(parts[0], 10);
|
11
|
+
const requestedVersion = parseInt(parts[1].split('=')[1], 10);
|
12
|
+
const availableVersions = parts[2].split('=')[1].split(',').map(v => parseInt(v, 10));
|
13
|
+
const errorReporting = parseInt(parts[3].split('=')[1], 10);
|
14
|
+
return {
|
15
|
+
responseVersion,
|
16
|
+
requestedVersion,
|
17
|
+
availableVersions,
|
18
|
+
errorReporting,
|
19
|
+
};
|
20
|
+
}
|
21
|
+
class APIVersion {
|
22
|
+
requestedVersion;
|
23
|
+
version;
|
24
|
+
deprecation;
|
25
|
+
sunsetDate;
|
26
|
+
availableVersions;
|
27
|
+
errors;
|
28
|
+
constructor(requestedVersion, version, deprecation, sunset, availableVersions, errors) {
|
29
|
+
this.requestedVersion = requestedVersion ?? constants_1.VERSION_NUMBER_NOT_DEFINED;
|
30
|
+
this.version = version;
|
31
|
+
this.deprecation = deprecation;
|
32
|
+
this.sunsetDate = sunset;
|
33
|
+
this.availableVersions = availableVersions;
|
34
|
+
this.errors = errors;
|
35
|
+
}
|
36
|
+
static fromHeaders(headers) {
|
37
|
+
const lowerCaseHeaders = Object.keys(headers)
|
38
|
+
.reduce((acc, key) => {
|
39
|
+
acc[key.toLowerCase()] = headers[key];
|
40
|
+
return acc;
|
41
|
+
}, {});
|
42
|
+
if (!Object.prototype.hasOwnProperty.call(lowerCaseHeaders, constants_1.VERSION_INFO_HEADER)) {
|
43
|
+
throw new Error('Developer: you have attempted to construct an API version from a response without headers. ' +
|
44
|
+
'Use a static helper method to check if the response is versioned first.');
|
45
|
+
}
|
46
|
+
const parsedVersionInfo = parseVersionInfoValue(lowerCaseHeaders[constants_1.VERSION_INFO_HEADER]);
|
47
|
+
const deprecation = ((value) => {
|
48
|
+
if (!value)
|
49
|
+
return null;
|
50
|
+
if (!value.startsWith('@')) {
|
51
|
+
throw new Error('Deprecation header must start with "@"');
|
52
|
+
}
|
53
|
+
const dateString = value.substring(1);
|
54
|
+
if (!/^\d+$/.test(dateString)) {
|
55
|
+
throw new Error(`Expected a Unix timestamp in Deprecation header, got: ${dateString}`);
|
56
|
+
}
|
57
|
+
const date = new Date(parseInt(dateString, 10) * 1000);
|
58
|
+
if (Number.isNaN(date.getTime())) {
|
59
|
+
throw new Error(`Invalid date in Deprecation header: ${dateString}`);
|
60
|
+
}
|
61
|
+
return date;
|
62
|
+
})(lowerCaseHeaders[constants_1.VERSION_DEPRECATION_HEADER]);
|
63
|
+
const sunset = ((value) => {
|
64
|
+
if (!value)
|
65
|
+
return null;
|
66
|
+
if (Number.isNaN(Date.parse(value))) {
|
67
|
+
throw new Error(`An invalid sunset date {value} was passed.`);
|
68
|
+
}
|
69
|
+
return new Date(value);
|
70
|
+
})(lowerCaseHeaders[constants_1.VERSION_SUNSET_HEADER]);
|
71
|
+
const errors = ((allErrorData) => {
|
72
|
+
if (!allErrorData)
|
73
|
+
return [];
|
74
|
+
const parsedErrorData = JSON.parse(allErrorData);
|
75
|
+
if (!Array.isArray(parsedErrorData)) {
|
76
|
+
throw new Error('Expected an array of VersioningErrorData objects in the error header');
|
77
|
+
}
|
78
|
+
return parsedErrorData.map((errorDataString) => {
|
79
|
+
const errorData = JSON.parse(errorDataString);
|
80
|
+
if (!Object.prototype.hasOwnProperty.call(errorData, 'error')) {
|
81
|
+
throw new Error('Expected an error message in the error data');
|
82
|
+
}
|
83
|
+
if (!Object.prototype.hasOwnProperty.call(errorData, 'level')) {
|
84
|
+
throw new Error('Expected an error level in the error data');
|
85
|
+
}
|
86
|
+
if (!Object.prototype.hasOwnProperty.call(errorData, 'code')) {
|
87
|
+
throw new Error('Expected an error code in the error data');
|
88
|
+
}
|
89
|
+
if (errorData.level === 'alert' || errorData.level === 'critical' || errorData.level === 'emergency') {
|
90
|
+
errorData.level = 'fatal';
|
91
|
+
}
|
92
|
+
return new VersioningError_1.default(errorData.error, errorData.level, errorData.code, sunset);
|
93
|
+
});
|
94
|
+
})(lowerCaseHeaders[constants_1.VERSION_ERRORS_HEADER]);
|
95
|
+
return new APIVersion(parsedVersionInfo.requestedVersion, parsedVersionInfo.responseVersion, deprecation, sunset, parsedVersionInfo.availableVersions, errors);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
exports.default = APIVersion;
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { VERSION_ERROR_LEVEL_ERROR, VERSION_ERROR_LEVEL_FATAL, VERSION_ERROR_LEVEL_WARNING } from "../constants";
|
2
|
+
export type VersionErrorLevel = typeof VERSION_ERROR_LEVEL_WARNING | typeof VERSION_ERROR_LEVEL_ERROR | typeof VERSION_ERROR_LEVEL_FATAL | null;
|
3
|
+
export default class VersioningError extends Error {
|
4
|
+
level: 'warning' | 'error' | 'fatal';
|
5
|
+
code: string;
|
6
|
+
sunsetDate: Date | null;
|
7
|
+
constructor(message: string, level: string, code: string, sunsetDate?: Date | null);
|
8
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const constants_1 = require("../constants");
|
4
|
+
class VersioningError extends Error {
|
5
|
+
level;
|
6
|
+
code;
|
7
|
+
sunsetDate;
|
8
|
+
constructor(message, level, code, sunsetDate = null) {
|
9
|
+
super(message);
|
10
|
+
this.name = 'VersionMismatchError';
|
11
|
+
if (![constants_1.VERSION_ERROR_LEVEL_WARNING, constants_1.VERSION_ERROR_LEVEL_ERROR, constants_1.VERSION_ERROR_LEVEL_FATAL].includes(level)) {
|
12
|
+
throw Error('Developer: you have passed an invalid error level: ' + level);
|
13
|
+
}
|
14
|
+
this.level = level;
|
15
|
+
this.code = code;
|
16
|
+
this.sunsetDate = sunsetDate;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
exports.default = VersioningError;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { AxiosResponse, AxiosInstance } from "axios";
|
2
|
+
import APIVersion from "./ApiVersion";
|
3
|
+
export declare const useVersion: (version: number) => {
|
4
|
+
transformRequest: ((data: object, headers: {
|
5
|
+
[key: string]: string;
|
6
|
+
}) => object)[];
|
7
|
+
};
|
8
|
+
export declare function handleVersioningErrorsInAxiosResponse(response: AxiosResponse): Promise<void>;
|
9
|
+
declare const _default: {
|
10
|
+
bindAxiosVersioningResponseErrorListener: (instance: AxiosInstance) => void;
|
11
|
+
isAxiosResponseVersioned: (response: AxiosResponse<any, any>) => boolean;
|
12
|
+
fromAxiosResponse: (response: AxiosResponse<any, any>) => APIVersion;
|
13
|
+
};
|
14
|
+
export default _default;
|
@@ -0,0 +1,102 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.handleVersioningErrorsInAxiosResponse = exports.useVersion = void 0;
|
7
|
+
const ApiVersion_1 = __importDefault(require("./ApiVersion"));
|
8
|
+
const sentry_1 = require("./sentry");
|
9
|
+
const constants_1 = require("./constants");
|
10
|
+
const helpers_1 = __importDefault(require("./helpers"));
|
11
|
+
const useVersion = (version) => {
|
12
|
+
return {
|
13
|
+
transformRequest: [(data, headers) => {
|
14
|
+
headers['Accept-Version'] = version.toString();
|
15
|
+
return data;
|
16
|
+
}],
|
17
|
+
};
|
18
|
+
};
|
19
|
+
exports.useVersion = useVersion;
|
20
|
+
const isAxiosResponseVersioned = (response) => {
|
21
|
+
return Object.prototype.hasOwnProperty.call(response.headers, constants_1.VERSION_INFO_HEADER);
|
22
|
+
};
|
23
|
+
const fromAxiosResponse = (response) => {
|
24
|
+
if (!isAxiosResponseVersioned(response)) {
|
25
|
+
throw new Error('Developer: you have attempted to construct an API version from a response without headers. ' +
|
26
|
+
'Use the static isVersioned method to check if the response is versioned first.');
|
27
|
+
}
|
28
|
+
return ApiVersion_1.default.fromHeaders(response.headers);
|
29
|
+
};
|
30
|
+
async function handleVersioningErrorsInAxiosResponse(response) {
|
31
|
+
if (response.status > 300) {
|
32
|
+
return;
|
33
|
+
}
|
34
|
+
if (!(response.request instanceof XMLHttpRequest)) {
|
35
|
+
return;
|
36
|
+
}
|
37
|
+
if (!isAxiosResponseVersioned(response)) {
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
let apiVersion;
|
41
|
+
try {
|
42
|
+
apiVersion = fromAxiosResponse(response);
|
43
|
+
}
|
44
|
+
catch (e) {
|
45
|
+
console.error('Pixieset Versioning: Error constructing API version from response', e, response);
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
const url = response.request.responseURL;
|
49
|
+
if (apiVersion.errors.length === 0) {
|
50
|
+
return;
|
51
|
+
}
|
52
|
+
const Sentry = await (0, sentry_1.getSentry)();
|
53
|
+
apiVersion.errors.forEach((error) => {
|
54
|
+
const baseStyle = '';
|
55
|
+
let style;
|
56
|
+
let logFunction;
|
57
|
+
let emoji;
|
58
|
+
switch (error.level) {
|
59
|
+
case constants_1.VERSION_ERROR_LEVEL_WARNING:
|
60
|
+
style = `${baseStyle}`;
|
61
|
+
logFunction = 'warn';
|
62
|
+
emoji = '⚠️';
|
63
|
+
break;
|
64
|
+
case constants_1.VERSION_ERROR_LEVEL_ERROR:
|
65
|
+
style = `${baseStyle}`;
|
66
|
+
logFunction = 'error';
|
67
|
+
emoji = '🚫';
|
68
|
+
break;
|
69
|
+
case constants_1.VERSION_ERROR_LEVEL_FATAL:
|
70
|
+
style = `${baseStyle} font-size: 14px;`;
|
71
|
+
logFunction = 'error';
|
72
|
+
emoji = '🚫';
|
73
|
+
break;
|
74
|
+
}
|
75
|
+
console[logFunction](`%c${emoji} ${error.level.toUpperCase()}: ${error.message}`, style, {
|
76
|
+
url,
|
77
|
+
stacktrace: (0, helpers_1.default)(error.stack),
|
78
|
+
});
|
79
|
+
if (!Sentry || error.level === constants_1.VERSION_ERROR_LEVEL_WARNING) {
|
80
|
+
return;
|
81
|
+
}
|
82
|
+
Sentry.captureException(error, {
|
83
|
+
level: error.level,
|
84
|
+
extra: {
|
85
|
+
url,
|
86
|
+
stacktrace: error.stack ?? '[stack trace not available]',
|
87
|
+
},
|
88
|
+
});
|
89
|
+
});
|
90
|
+
}
|
91
|
+
exports.handleVersioningErrorsInAxiosResponse = handleVersioningErrorsInAxiosResponse;
|
92
|
+
const bindAxiosVersioningResponseErrorListener = (instance) => {
|
93
|
+
instance.interceptors.response.use(async (response) => {
|
94
|
+
await handleVersioningErrorsInAxiosResponse(response);
|
95
|
+
return response;
|
96
|
+
});
|
97
|
+
};
|
98
|
+
exports.default = {
|
99
|
+
bindAxiosVersioningResponseErrorListener,
|
100
|
+
isAxiosResponseVersioned,
|
101
|
+
fromAxiosResponse,
|
102
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import VersioningError from "./Error/VersioningError";
|
2
|
+
import { ExclusiveEventHintOrCaptureContext } from '@sentry/core/build/types-ts3.8/utils/prepareEvent';
|
3
|
+
interface HttpResponse {
|
4
|
+
headers: Record<string, string>;
|
5
|
+
status: number;
|
6
|
+
url: string;
|
7
|
+
}
|
8
|
+
interface HttpOptions {
|
9
|
+
headers?: Record<string, string>;
|
10
|
+
[key: string]: unknown;
|
11
|
+
}
|
12
|
+
declare const _default: {
|
13
|
+
useVersion: (version: number, existingOptions: HttpOptions) => HttpOptions;
|
14
|
+
handleVersioningErrorsInCapacitorResponse: (response: HttpResponse, captureExceptionCallback: (error: VersioningError, hint: ExclusiveEventHintOrCaptureContext) => void) => Promise<void>;
|
15
|
+
};
|
16
|
+
export default _default;
|
@@ -0,0 +1,90 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const ApiVersion_1 = __importDefault(require("./ApiVersion"));
|
7
|
+
const constants_1 = require("./constants");
|
8
|
+
const helpers_1 = __importDefault(require("./helpers"));
|
9
|
+
const useVersion = (version, existingOptions) => {
|
10
|
+
return {
|
11
|
+
...existingOptions,
|
12
|
+
headers: {
|
13
|
+
...existingOptions.headers,
|
14
|
+
'Accept-Version': version.toString()
|
15
|
+
}
|
16
|
+
};
|
17
|
+
};
|
18
|
+
const isCapacitorResponseVersioned = (response) => {
|
19
|
+
return Object.prototype.hasOwnProperty.call(response.headers, constants_1.VERSION_INFO_HEADER);
|
20
|
+
};
|
21
|
+
const fromCapacitorResponse = (response) => {
|
22
|
+
if (!isCapacitorResponseVersioned(response)) {
|
23
|
+
throw new Error('Developer: you have attempted to construct an API version from a response without headers. ' +
|
24
|
+
'Use the static isVersioned method to check if the response is versioned first.');
|
25
|
+
}
|
26
|
+
return ApiVersion_1.default.fromHeaders(response.headers);
|
27
|
+
};
|
28
|
+
const handleVersioningErrorsInCapacitorResponse = async (response, captureExceptionCallback) => {
|
29
|
+
if (response.status > 300) {
|
30
|
+
return;
|
31
|
+
}
|
32
|
+
if (!isCapacitorResponseVersioned(response)) {
|
33
|
+
return;
|
34
|
+
}
|
35
|
+
let apiVersion;
|
36
|
+
try {
|
37
|
+
apiVersion = fromCapacitorResponse(response);
|
38
|
+
}
|
39
|
+
catch (e) {
|
40
|
+
console.error('Pixieset Versioning: Error constructing API version from response', e, response);
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
const url = response.url;
|
44
|
+
if (apiVersion.errors.length === 0) {
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
apiVersion.errors.forEach((error) => {
|
48
|
+
const baseStyle = '';
|
49
|
+
let style;
|
50
|
+
let logFunction;
|
51
|
+
let emoji;
|
52
|
+
switch (error.level) {
|
53
|
+
case constants_1.VERSION_ERROR_LEVEL_WARNING:
|
54
|
+
style = `${baseStyle}`;
|
55
|
+
logFunction = 'warn';
|
56
|
+
emoji = '⚠️';
|
57
|
+
break;
|
58
|
+
case constants_1.VERSION_ERROR_LEVEL_ERROR:
|
59
|
+
style = `${baseStyle}`;
|
60
|
+
logFunction = 'error';
|
61
|
+
emoji = '🚫';
|
62
|
+
break;
|
63
|
+
case constants_1.VERSION_ERROR_LEVEL_FATAL:
|
64
|
+
style = `${baseStyle} font-size: 14px;`;
|
65
|
+
logFunction = 'error';
|
66
|
+
emoji = '🚫';
|
67
|
+
break;
|
68
|
+
}
|
69
|
+
console[logFunction](`%c${emoji} ${error.level.toUpperCase()}: ${error.message}`, style, {
|
70
|
+
url,
|
71
|
+
stacktrace: (0, helpers_1.default)(error.stack),
|
72
|
+
});
|
73
|
+
if (error.level === constants_1.VERSION_ERROR_LEVEL_WARNING) {
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
captureExceptionCallback(error, {
|
77
|
+
captureContext: {
|
78
|
+
level: error.level,
|
79
|
+
extra: {
|
80
|
+
url,
|
81
|
+
stacktrace: error.stack ?? '[stack trace not available]',
|
82
|
+
},
|
83
|
+
},
|
84
|
+
});
|
85
|
+
});
|
86
|
+
};
|
87
|
+
exports.default = {
|
88
|
+
useVersion,
|
89
|
+
handleVersioningErrorsInCapacitorResponse,
|
90
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
export declare const ERROR_REPORTING_NONE = 0;
|
2
|
+
export declare const ERROR_REPORTING_SHOW_CONSOLE_ERRORS = 1;
|
3
|
+
export declare const ERROR_REPORTING_SHOW_SENTRY_ERRORS = 2;
|
4
|
+
export declare const ERROR_REPORTING_ALL = 3;
|
5
|
+
export declare const VERSION_ERROR_LEVEL_WARNING = "warning";
|
6
|
+
export declare const VERSION_ERROR_LEVEL_ERROR = "error";
|
7
|
+
export declare const VERSION_ERROR_LEVEL_FATAL = "fatal";
|
8
|
+
export declare const VERSION_NUMBER_NOT_DEFINED = -1;
|
9
|
+
export declare const VERSION_INFO_HEADER = "x-api-version-info";
|
10
|
+
export declare const VERSION_ERRORS_HEADER = "x-api-version-errors";
|
11
|
+
export declare const VERSION_DEPRECATION_HEADER = "deprecation";
|
12
|
+
export declare const VERSION_SUNSET_HEADER = "sunset";
|
@@ -0,0 +1,15 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.VERSION_SUNSET_HEADER = exports.VERSION_DEPRECATION_HEADER = exports.VERSION_ERRORS_HEADER = exports.VERSION_INFO_HEADER = exports.VERSION_NUMBER_NOT_DEFINED = exports.VERSION_ERROR_LEVEL_FATAL = exports.VERSION_ERROR_LEVEL_ERROR = exports.VERSION_ERROR_LEVEL_WARNING = exports.ERROR_REPORTING_ALL = exports.ERROR_REPORTING_SHOW_SENTRY_ERRORS = exports.ERROR_REPORTING_SHOW_CONSOLE_ERRORS = exports.ERROR_REPORTING_NONE = void 0;
|
4
|
+
exports.ERROR_REPORTING_NONE = 0;
|
5
|
+
exports.ERROR_REPORTING_SHOW_CONSOLE_ERRORS = 1;
|
6
|
+
exports.ERROR_REPORTING_SHOW_SENTRY_ERRORS = 2;
|
7
|
+
exports.ERROR_REPORTING_ALL = 3;
|
8
|
+
exports.VERSION_ERROR_LEVEL_WARNING = 'warning';
|
9
|
+
exports.VERSION_ERROR_LEVEL_ERROR = 'error';
|
10
|
+
exports.VERSION_ERROR_LEVEL_FATAL = 'fatal';
|
11
|
+
exports.VERSION_NUMBER_NOT_DEFINED = -1;
|
12
|
+
exports.VERSION_INFO_HEADER = 'x-api-version-info';
|
13
|
+
exports.VERSION_ERRORS_HEADER = 'x-api-version-errors';
|
14
|
+
exports.VERSION_DEPRECATION_HEADER = 'deprecation';
|
15
|
+
exports.VERSION_SUNSET_HEADER = 'sunset';
|
package/dist/helpers.js
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
const traceToObject = (stack) => {
|
4
|
+
if (stack === undefined) {
|
5
|
+
return {};
|
6
|
+
}
|
7
|
+
const stackLines = stack.split('\n');
|
8
|
+
const parsedStack = {};
|
9
|
+
stackLines.forEach((line, index) => {
|
10
|
+
if (line.trim()) {
|
11
|
+
parsedStack[`- ${index}`] = line.trim();
|
12
|
+
}
|
13
|
+
});
|
14
|
+
return parsedStack;
|
15
|
+
};
|
16
|
+
exports.default = traceToObject;
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
export * from './ApiVersion';
|
2
|
+
export * from './Error/VersioningError';
|
3
|
+
export * from './axios_helpers';
|
4
|
+
export { useVersion } from './axios_helpers';
|
5
|
+
export { ERROR_REPORTING_ALL } from "./constants";
|
6
|
+
export { ERROR_REPORTING_SHOW_SENTRY_ERRORS } from "./constants";
|
7
|
+
export { ERROR_REPORTING_SHOW_CONSOLE_ERRORS } from "./constants";
|
8
|
+
export { ERROR_REPORTING_NONE } from "./constants";
|
9
|
+
export { VERSION_ERROR_LEVEL_FATAL } from "./constants";
|
10
|
+
export { VERSION_ERROR_LEVEL_ERROR } from "./constants";
|
11
|
+
export { VERSION_ERROR_LEVEL_WARNING } from "./constants";
|
12
|
+
export { VERSION_SUNSET_HEADER } from "./constants";
|
13
|
+
export { VERSION_DEPRECATION_HEADER } from "./constants";
|
14
|
+
export { VERSION_INFO_HEADER } from "./constants";
|
15
|
+
export { VERSION_NUMBER_NOT_DEFINED } from "./constants";
|
16
|
+
export { VersioningHeaders } from "./types";
|
17
|
+
export { VersionSunsetDate } from "./types";
|
18
|
+
export { VersionDeprecation } from "./types";
|
19
|
+
export { VersionInfo } from "./types";
|
20
|
+
export { VersionInfoValue } from "./types";
|
package/dist/index.js
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
exports.VERSION_NUMBER_NOT_DEFINED = exports.VERSION_INFO_HEADER = exports.VERSION_DEPRECATION_HEADER = exports.VERSION_SUNSET_HEADER = exports.VERSION_ERROR_LEVEL_WARNING = exports.VERSION_ERROR_LEVEL_ERROR = exports.VERSION_ERROR_LEVEL_FATAL = exports.ERROR_REPORTING_NONE = exports.ERROR_REPORTING_SHOW_CONSOLE_ERRORS = exports.ERROR_REPORTING_SHOW_SENTRY_ERRORS = exports.ERROR_REPORTING_ALL = exports.useVersion = void 0;
|
18
|
+
__exportStar(require("./ApiVersion"), exports);
|
19
|
+
__exportStar(require("./Error/VersioningError"), exports);
|
20
|
+
__exportStar(require("./axios_helpers"), exports);
|
21
|
+
var axios_helpers_1 = require("./axios_helpers");
|
22
|
+
Object.defineProperty(exports, "useVersion", { enumerable: true, get: function () { return axios_helpers_1.useVersion; } });
|
23
|
+
var constants_1 = require("./constants");
|
24
|
+
Object.defineProperty(exports, "ERROR_REPORTING_ALL", { enumerable: true, get: function () { return constants_1.ERROR_REPORTING_ALL; } });
|
25
|
+
var constants_2 = require("./constants");
|
26
|
+
Object.defineProperty(exports, "ERROR_REPORTING_SHOW_SENTRY_ERRORS", { enumerable: true, get: function () { return constants_2.ERROR_REPORTING_SHOW_SENTRY_ERRORS; } });
|
27
|
+
var constants_3 = require("./constants");
|
28
|
+
Object.defineProperty(exports, "ERROR_REPORTING_SHOW_CONSOLE_ERRORS", { enumerable: true, get: function () { return constants_3.ERROR_REPORTING_SHOW_CONSOLE_ERRORS; } });
|
29
|
+
var constants_4 = require("./constants");
|
30
|
+
Object.defineProperty(exports, "ERROR_REPORTING_NONE", { enumerable: true, get: function () { return constants_4.ERROR_REPORTING_NONE; } });
|
31
|
+
var constants_5 = require("./constants");
|
32
|
+
Object.defineProperty(exports, "VERSION_ERROR_LEVEL_FATAL", { enumerable: true, get: function () { return constants_5.VERSION_ERROR_LEVEL_FATAL; } });
|
33
|
+
var constants_6 = require("./constants");
|
34
|
+
Object.defineProperty(exports, "VERSION_ERROR_LEVEL_ERROR", { enumerable: true, get: function () { return constants_6.VERSION_ERROR_LEVEL_ERROR; } });
|
35
|
+
var constants_7 = require("./constants");
|
36
|
+
Object.defineProperty(exports, "VERSION_ERROR_LEVEL_WARNING", { enumerable: true, get: function () { return constants_7.VERSION_ERROR_LEVEL_WARNING; } });
|
37
|
+
var constants_8 = require("./constants");
|
38
|
+
Object.defineProperty(exports, "VERSION_SUNSET_HEADER", { enumerable: true, get: function () { return constants_8.VERSION_SUNSET_HEADER; } });
|
39
|
+
var constants_9 = require("./constants");
|
40
|
+
Object.defineProperty(exports, "VERSION_DEPRECATION_HEADER", { enumerable: true, get: function () { return constants_9.VERSION_DEPRECATION_HEADER; } });
|
41
|
+
var constants_10 = require("./constants");
|
42
|
+
Object.defineProperty(exports, "VERSION_INFO_HEADER", { enumerable: true, get: function () { return constants_10.VERSION_INFO_HEADER; } });
|
43
|
+
var constants_11 = require("./constants");
|
44
|
+
Object.defineProperty(exports, "VERSION_NUMBER_NOT_DEFINED", { enumerable: true, get: function () { return constants_11.VERSION_NUMBER_NOT_DEFINED; } });
|
package/dist/sentry.d.ts
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
import { captureMessage, captureException } from "@sentry/core/build/types-ts3.8";
|
2
|
+
export type SentryCore = {
|
3
|
+
captureMessage: typeof captureMessage;
|
4
|
+
captureException: typeof captureException;
|
5
|
+
};
|
6
|
+
declare global {
|
7
|
+
var Sentry: SentryCore | undefined;
|
8
|
+
}
|
9
|
+
export declare function getSentry(): Promise<SentryCore | undefined>;
|
package/dist/sentry.js
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getSentry = void 0;
|
4
|
+
async function getSentry() {
|
5
|
+
if (typeof global.Sentry !== "object") {
|
6
|
+
return undefined;
|
7
|
+
}
|
8
|
+
if (typeof global.Sentry.captureMessage !== "function"
|
9
|
+
|| typeof global.Sentry.captureException !== "function") {
|
10
|
+
return undefined;
|
11
|
+
}
|
12
|
+
return global.Sentry;
|
13
|
+
}
|
14
|
+
exports.getSentry = getSentry;
|
package/package.json
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
{
|
2
|
+
"name": "@pixieset/versioning-js",
|
3
|
+
"version": "1.0.13",
|
4
|
+
"description": "Front end support for Pixieset versioning",
|
5
|
+
"main": "index.js",
|
6
|
+
"repository": {
|
7
|
+
"type": "git",
|
8
|
+
"url": "git@bitbucket.org:pixieset/versioning-js.git"
|
9
|
+
},
|
10
|
+
"author": "Aron Beal <aron.beal@pixieset.com>",
|
11
|
+
"license": "UNLICENSED",
|
12
|
+
"files": [
|
13
|
+
"dist"
|
14
|
+
],
|
15
|
+
"devDependencies": {
|
16
|
+
"@types/axios": "^0.14",
|
17
|
+
"@types/jest": "^29",
|
18
|
+
"@typescript-eslint/eslint-plugin": "^8.7.0",
|
19
|
+
"@typescript-eslint/parser": "^8.7.0",
|
20
|
+
"eslint": "^8",
|
21
|
+
"jest": "^29",
|
22
|
+
"jest-resolve": "^29",
|
23
|
+
"ts-jest": "^29",
|
24
|
+
"ts-node": "^10",
|
25
|
+
"typescript": "5.1"
|
26
|
+
},
|
27
|
+
"dependencies": {
|
28
|
+
"@sentry/core": "^8",
|
29
|
+
"@sentry/types": "^8",
|
30
|
+
"@types/node": "^20",
|
31
|
+
"axios": "^1.7.7"
|
32
|
+
},
|
33
|
+
"scripts": {
|
34
|
+
"build": "tsc",
|
35
|
+
"watch": "tsc --watch",
|
36
|
+
"lint": "eslint . --ext .ts",
|
37
|
+
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
38
|
+
"test": "TZ=UTC jest",
|
39
|
+
"prepack": "yarn build",
|
40
|
+
"preversion": "yarn test",
|
41
|
+
"version": "yarn build"
|
42
|
+
},
|
43
|
+
"directories": {
|
44
|
+
"test": "tests"
|
45
|
+
},
|
46
|
+
"keywords": [
|
47
|
+
"pixieset",
|
48
|
+
"versioning"
|
49
|
+
],
|
50
|
+
"bugs": {
|
51
|
+
"url": "https://bitbucket.org/pixieset/versioning-js/issues"
|
52
|
+
},
|
53
|
+
"homepage": "https://bitbucket.org/pixieset/versioning-js#readme"
|
54
|
+
}
|