@forge/storage-data-recovery 2.0.0-next.0

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.txt ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2025 Atlassian
2
+ Permission is hereby granted to use this software in accordance with the terms
3
+ and conditions outlined in the Atlassian Developer Terms, which can be found
4
+ at the following URL:
5
+ https://developer.atlassian.com/platform/marketplace/atlassian-developer-terms/
6
+ By using this software, you agree to comply with these terms and conditions.
7
+ If you do not agree with these terms, you are not permitted to use this software.
package/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Forge Storage Data Recovery
2
+
3
+ Standalone Library for Forge Storage Data Recovery operations.
4
+
5
+ ## Usage
6
+
7
+ ```typescript
8
+ import { WhereConditions } from '@forge/kvs';
9
+ import { dataRecovery, StorageType, SnapshotNotFoundError } from '@forge/storage-data-recovery';
10
+
11
+ // Query data from a storage snapshot
12
+ const results = await dataRecovery('hot117987', 'kvs') // StorageType: 'kvs' | 'secret' | 'custom_entity'
13
+ .query()
14
+ .where('key', WhereConditions.beginsWith('value'))
15
+ .limit(10)
16
+ .cursor('...')
17
+ .getMany();
18
+
19
+ // Results structure
20
+ console.log(results.results); // Array of { key: string, value: T }
21
+ console.log(results.nextCursor); // Optional cursor for pagination
22
+
23
+ // Error handling
24
+ try {
25
+ const data = await dataRecovery('nonexistent-snapshot', 'kvs')
26
+ .query()
27
+ .getMany();
28
+ } catch (error) {
29
+ if (error instanceof SnapshotNotFoundError) {
30
+ console.log('Snapshot not found');
31
+ }
32
+ }
33
+ ```
34
+
35
+ ## API
36
+
37
+ ### `dataRecovery(snapshotName: string, storageType: StorageType)`
38
+
39
+ Creates a recovery instance for the specified snapshot and storage type.
40
+
41
+ **Parameters:**
42
+ - `snapshotName`: Name of the storage snapshot (e.g., 'hot117987')
43
+ - `storageType`: Type of storage - `'kvs' | 'secret' | 'custom_entity'`
44
+
45
+ **Returns:** `DataRecoveryImpl` instance with query capabilities
46
+
47
+ ### Query Methods
48
+
49
+ - `.query()`: Start building a query
50
+ - `.where(property, condition)`: Filter by key conditions (supports WhereConditions from @forge/kvs)
51
+ - `.limit(number)`: Limit number of results
52
+ - `.cursor(string)`: Set pagination cursor
53
+ - `.getMany<T>()`: Execute query and return results
54
+
55
+ ### Error Types
56
+
57
+ - `RecoveryException`: Base recovery error
58
+ - `SnapshotNotFoundError`: Thrown when snapshot doesn't exist
59
+ - `InvalidStorageTypeError`: Thrown for invalid storage types
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=global-data-recovery.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-data-recovery.test.d.ts","sourceRoot":"","sources":["../../src/__test__/global-data-recovery.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const kvs_1 = require("@forge/kvs");
4
+ const index_1 = require("../index");
5
+ const storage_client_1 = require("../storage-client");
6
+ const data_recovery_1 = require("../data-recovery");
7
+ const types_1 = require("../types");
8
+ function prepare(response, snapshotName, storageType) {
9
+ const apiClient = jest.fn().mockResolvedValueOnce(response);
10
+ const storageClient = new storage_client_1.StorageClient(apiClient);
11
+ const sut = new data_recovery_1.DataRecoveryImpl(storageClient, snapshotName, storageType);
12
+ return {
13
+ apiClient,
14
+ storageClient,
15
+ sut
16
+ };
17
+ }
18
+ describe('dataRecovery', () => {
19
+ const snapshotName = 'test-snapshot';
20
+ const traceId = 'trace-id';
21
+ it('should be defined', () => {
22
+ expect(index_1.dataRecovery).toBeDefined();
23
+ });
24
+ it('should return a data recovery instance', () => {
25
+ const dataRecoveryInstance = (0, index_1.dataRecovery)(snapshotName, types_1.StorageTypeKVS);
26
+ expect(dataRecoveryInstance).toBeDefined();
27
+ });
28
+ it('should throw an error if the storage type is invalid', () => {
29
+ expect(() => (0, index_1.dataRecovery)(snapshotName, 'invalid')).toThrow(index_1.InvalidStorageTypeError);
30
+ });
31
+ it('should return a data recovery instance with the correct storage type', () => {
32
+ const dataRecoveryInstance = (0, index_1.dataRecovery)(snapshotName, types_1.StorageTypeKVS);
33
+ expect(dataRecoveryInstance.query).toBeDefined();
34
+ expect(dataRecoveryInstance.query().where('key', kvs_1.WhereConditions.beginsWith('test')).getMany).toBeDefined();
35
+ expect(dataRecoveryInstance.query().cursor('test').getMany).toBeDefined();
36
+ expect(dataRecoveryInstance.query().limit(10).getMany).toBeDefined();
37
+ });
38
+ it('should make a REST call to the data recovery API', async () => {
39
+ const response = new Response(JSON.stringify({
40
+ cursor: 'third-page',
41
+ data: [
42
+ {
43
+ key: 'foo',
44
+ value: { foo: 'bar' },
45
+ entityName: 'example',
46
+ provider: 'custom_entity',
47
+ createdAt: 1753852892506,
48
+ updatedAt: 1753852902502
49
+ }
50
+ ]
51
+ }), {
52
+ status: 200,
53
+ headers: { 'x-trace-id': traceId }
54
+ });
55
+ const { sut, apiClient } = prepare(response, snapshotName, types_1.StorageTypeCustomEntity);
56
+ const rs = await sut
57
+ .query()
58
+ .cursor('second-page')
59
+ .limit(1)
60
+ .where('key', kvs_1.WhereConditions.beginsWith('fo'))
61
+ .getMany();
62
+ expect(rs).toEqual({
63
+ results: [
64
+ {
65
+ key: 'foo',
66
+ value: { foo: 'bar' },
67
+ entityName: 'example',
68
+ provider: 'custom_entity',
69
+ createdAt: 1753852892506,
70
+ updatedAt: 1753852902502
71
+ }
72
+ ],
73
+ nextCursor: 'third-page'
74
+ });
75
+ expect(apiClient).toHaveBeenCalledWith('/api/v1/data-recovery/query', {
76
+ body: JSON.stringify({
77
+ snapshotName: snapshotName,
78
+ provider: types_1.StorageTypeCustomEntity,
79
+ limit: 1,
80
+ after: 'second-page',
81
+ where: [{ property: 'key', condition: 'BEGINS_WITH', values: ['fo'] }]
82
+ }),
83
+ headers: {
84
+ 'content-type': 'application/json'
85
+ },
86
+ method: 'POST'
87
+ });
88
+ });
89
+ it('should throw a SnapshotNotFoundError if the snapshot is not found', async () => {
90
+ const response = new Response('not found', {
91
+ status: 404,
92
+ headers: { 'x-trace-id': traceId }
93
+ });
94
+ const { sut } = prepare(response, snapshotName, types_1.StorageTypeCustomEntity);
95
+ const query = sut.query().cursor('second-page').limit(1).where('key', kvs_1.WhereConditions.beginsWith('fo'));
96
+ await expect(query.getMany()).rejects.toMatchObject(new index_1.SnapshotNotFoundError(snapshotName));
97
+ });
98
+ });
@@ -0,0 +1,23 @@
1
+ import { WhereConditions } from '@forge/kvs';
2
+ import { StorageClient } from './storage-client';
3
+ import { ListResult, RecoveryQueryBuilder, StorageType } from './types';
4
+ import { QueryOptions } from '@forge/kvs/out/interfaces/query';
5
+ export declare class RecoveryQueryBuilderImpl implements RecoveryQueryBuilder {
6
+ private storageClient;
7
+ private snapshotName;
8
+ private storageType;
9
+ private options;
10
+ constructor(storageClient: StorageClient, snapshotName: string, storageType: StorageType, options?: QueryOptions);
11
+ where(property: 'key', condition: ReturnType<typeof WhereConditions.beginsWith>): this;
12
+ cursor(cursor: string): this;
13
+ limit(limit: number): this;
14
+ getMany<T>(): Promise<ListResult<T>>;
15
+ }
16
+ export declare class DataRecoveryImpl {
17
+ private storageClient;
18
+ private snapshotName;
19
+ private storageType;
20
+ constructor(storageClient: StorageClient, snapshotName: string, storageType: StorageType);
21
+ query(): RecoveryQueryBuilder;
22
+ }
23
+ //# sourceMappingURL=data-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-recovery.d.ts","sourceRoot":"","sources":["../src/data-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAE/D,qBAAa,wBAAyB,YAAW,oBAAoB;IAEjE,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,OAAO;gBAHP,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,WAAW,EACxB,OAAO,GAAE,YAAiB;IAGpC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,UAAU,CAAC,GAAG,IAAI;IAKtF,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK5B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKpB,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;CAS3C;AAED,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,WAAW;gBAFX,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,WAAW;IAGlC,KAAK,IAAI,oBAAoB;CAG9B"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DataRecoveryImpl = exports.RecoveryQueryBuilderImpl = void 0;
4
+ class RecoveryQueryBuilderImpl {
5
+ storageClient;
6
+ snapshotName;
7
+ storageType;
8
+ options;
9
+ constructor(storageClient, snapshotName, storageType, options = {}) {
10
+ this.storageClient = storageClient;
11
+ this.snapshotName = snapshotName;
12
+ this.storageType = storageType;
13
+ this.options = options;
14
+ }
15
+ where(property, condition) {
16
+ this.options.where = [{ property, ...condition }];
17
+ return this;
18
+ }
19
+ cursor(cursor) {
20
+ this.options.cursor = cursor;
21
+ return this;
22
+ }
23
+ limit(limit) {
24
+ this.options.limit = limit;
25
+ return this;
26
+ }
27
+ async getMany() {
28
+ return await this.storageClient.query({
29
+ snapshotName: this.snapshotName,
30
+ provider: this.storageType,
31
+ limit: this.options.limit,
32
+ after: this.options.cursor,
33
+ where: this.options.where
34
+ });
35
+ }
36
+ }
37
+ exports.RecoveryQueryBuilderImpl = RecoveryQueryBuilderImpl;
38
+ class DataRecoveryImpl {
39
+ storageClient;
40
+ snapshotName;
41
+ storageType;
42
+ constructor(storageClient, snapshotName, storageType) {
43
+ this.storageClient = storageClient;
44
+ this.snapshotName = snapshotName;
45
+ this.storageType = storageType;
46
+ }
47
+ query() {
48
+ return new RecoveryQueryBuilderImpl(this.storageClient, this.snapshotName, this.storageType);
49
+ }
50
+ }
51
+ exports.DataRecoveryImpl = DataRecoveryImpl;
@@ -0,0 +1,11 @@
1
+ export declare class RecoveryException extends Error {
2
+ readonly code?: string | undefined;
3
+ constructor(message: string, code?: string | undefined);
4
+ }
5
+ export declare class SnapshotNotFoundError extends RecoveryException {
6
+ constructor(snapshotName: string);
7
+ }
8
+ export declare class InvalidStorageTypeError extends RecoveryException {
9
+ constructor(storageType: string);
10
+ }
11
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,IAAI,CAAC;gBADrB,OAAO,EAAE,MAAM,EACC,IAAI,CAAC,oBAAQ;CAKhC;AAED,qBAAa,qBAAsB,SAAQ,iBAAiB;gBAC9C,YAAY,EAAE,MAAM;CAIjC;AAED,qBAAa,uBAAwB,SAAQ,iBAAiB;gBAChD,WAAW,EAAE,MAAM;CAIhC"}
package/out/errors.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidStorageTypeError = exports.SnapshotNotFoundError = exports.RecoveryException = void 0;
4
+ class RecoveryException extends Error {
5
+ code;
6
+ constructor(message, code) {
7
+ super(message);
8
+ this.code = code;
9
+ this.name = 'RecoveryException';
10
+ }
11
+ }
12
+ exports.RecoveryException = RecoveryException;
13
+ class SnapshotNotFoundError extends RecoveryException {
14
+ constructor(snapshotName) {
15
+ super(`Snapshot '${snapshotName}' not found`, 'SNAPSHOT_NOT_FOUND');
16
+ this.name = 'SnapshotNotFoundError';
17
+ }
18
+ }
19
+ exports.SnapshotNotFoundError = SnapshotNotFoundError;
20
+ class InvalidStorageTypeError extends RecoveryException {
21
+ constructor(storageType) {
22
+ super(`Invalid storage type '${storageType}'`, 'INVALID_STORAGE_TYPE');
23
+ this.name = 'InvalidStorageTypeError';
24
+ }
25
+ }
26
+ exports.InvalidStorageTypeError = InvalidStorageTypeError;
package/out/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { DataRecoveryImpl } from './data-recovery';
2
+ import { StorageType } from './types';
3
+ declare function dataRecovery(snapshotName: string, storageType: StorageType): DataRecoveryImpl;
4
+ export * from './errors';
5
+ export * from './types';
6
+ export { dataRecovery };
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EAAE,WAAW,EAA8D,MAAM,SAAS,CAAC;AA6ClG,iBAAS,YAAY,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,oBAMnE;AAED,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,CAAC"}
package/out/index.js ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dataRecovery = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const data_recovery_1 = require("./data-recovery");
6
+ const errors_1 = require("./errors");
7
+ const storage_client_1 = require("./storage-client");
8
+ const types_1 = require("./types");
9
+ async function fetchDirectlyToKVS(path, options) {
10
+ const runtime = global.__forge_runtime__;
11
+ if (!runtime) {
12
+ throw new Error('Forge runtime not found');
13
+ }
14
+ const { proxy, kvs, tracing } = runtime;
15
+ return await global.__forge_fetch__({ type: 'kvs' }, path, {
16
+ ...options,
17
+ headers: {
18
+ ...options?.headers,
19
+ Authorization: `Bearer ${proxy.token}`,
20
+ Host: kvs?.host,
21
+ 'x-b3-traceid': tracing.traceId,
22
+ 'x-b3-spanid': tracing.spanId
23
+ }
24
+ });
25
+ }
26
+ async function fetchViaFPP(path, options) {
27
+ return await global.__forge_fetch__({
28
+ type: 'kvs',
29
+ provider: 'app',
30
+ remote: 'kvs'
31
+ }, path, options);
32
+ }
33
+ function buildFetchClient() {
34
+ const runtime = global.__forge_runtime__;
35
+ if (runtime?.kvs?.url && runtime?.kvs?.host) {
36
+ return fetchDirectlyToKVS;
37
+ }
38
+ return fetchViaFPP;
39
+ }
40
+ function dataRecovery(snapshotName, storageType) {
41
+ if (![types_1.StorageTypeKVS, types_1.StorageTypeSecret, types_1.StorageTypeCustomEntity].includes(storageType)) {
42
+ throw new errors_1.InvalidStorageTypeError(storageType);
43
+ }
44
+ return new data_recovery_1.DataRecoveryImpl(new storage_client_1.StorageClient(buildFetchClient()), snapshotName, storageType);
45
+ }
46
+ exports.dataRecovery = dataRecovery;
47
+ tslib_1.__exportStar(require("./errors"), exports);
48
+ tslib_1.__exportStar(require("./types"), exports);
@@ -0,0 +1,9 @@
1
+ import { FetchMethod } from '@forge/api';
2
+ import { ListResult, QueryRequest } from './types';
3
+ export declare class StorageClient {
4
+ private apiClient;
5
+ constructor(apiClient: FetchMethod);
6
+ query<T>(body: QueryRequest): Promise<ListResult<T>>;
7
+ private request;
8
+ }
9
+ //# sourceMappingURL=storage-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-client.d.ts","sourceRoot":"","sources":["../src/storage-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAiB,MAAM,SAAS,CAAC;AAGlE,qBAAa,aAAa;IACZ,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,WAAW;IAEpC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAQ5C,OAAO;CAsBtB"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StorageClient = void 0;
4
+ const kvs_1 = require("@forge/kvs");
5
+ const errors_1 = require("./errors");
6
+ class StorageClient {
7
+ apiClient;
8
+ constructor(apiClient) {
9
+ this.apiClient = apiClient;
10
+ }
11
+ async query(body) {
12
+ const rs = await this.request(`/api/v1/data-recovery/query`, body);
13
+ return {
14
+ results: rs.data,
15
+ nextCursor: rs.cursor
16
+ };
17
+ }
18
+ async request(path, body) {
19
+ const requestBody = {
20
+ method: 'POST',
21
+ body: JSON.stringify(body),
22
+ headers: {
23
+ 'content-type': 'application/json'
24
+ }
25
+ };
26
+ const response = await this.apiClient(path, requestBody);
27
+ const responseText = await response.text();
28
+ if (response.status === 404) {
29
+ throw new errors_1.SnapshotNotFoundError(body.snapshotName);
30
+ }
31
+ try {
32
+ return JSON.parse(responseText);
33
+ }
34
+ catch (error) {
35
+ throw new kvs_1.ForgeKvsError(`Unexpected error. Response was not valid JSON: ${responseText}`);
36
+ }
37
+ }
38
+ }
39
+ exports.StorageClient = StorageClient;
package/out/types.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { WhereConditions } from '@forge/kvs';
2
+ export declare type QueryWhere = {
3
+ condition: 'BEGINS_WITH';
4
+ property: 'key';
5
+ values: Array<unknown>;
6
+ };
7
+ export declare type QueryRequest = {
8
+ snapshotName: string;
9
+ provider: StorageType;
10
+ limit?: number;
11
+ after?: string;
12
+ where?: Array<QueryWhere>;
13
+ };
14
+ export declare type QueryResponse<T> = {
15
+ data: Array<DataRecoverySchema<T>>;
16
+ cursor?: string;
17
+ };
18
+ export declare type DataRecoverySchema<T> = {
19
+ key: string;
20
+ value: T;
21
+ entityName?: string;
22
+ provider: 'kvs' | 'secret' | 'custom_entity';
23
+ createdAt: number;
24
+ updatedAt: number;
25
+ };
26
+ export declare const StorageTypeKVS = "kvs";
27
+ export declare const StorageTypeSecret = "secret";
28
+ export declare const StorageTypeCustomEntity = "custom_entity";
29
+ export declare type StorageType = 'kvs' | 'secret' | 'custom_entity';
30
+ export interface ListResult<T> {
31
+ results: DataRecoverySchema<T>[];
32
+ nextCursor?: string;
33
+ }
34
+ export interface RecoveryQueryBuilder {
35
+ where(property: 'key', condition: ReturnType<typeof WhereConditions.beginsWith>): RecoveryQueryBuilder;
36
+ cursor(cursor: string): RecoveryQueryBuilder;
37
+ limit(limit: number): RecoveryQueryBuilder;
38
+ getMany<T>(): Promise<ListResult<T>>;
39
+ }
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,oBAAY,UAAU,GAAG;IACvB,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;CACxB,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;CAC3B,CAAC;AAEF,oBAAY,aAAa,CAAC,CAAC,IAAI;IAC7B,IAAI,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,oBAAY,kBAAkB,CAAC,CAAC,IAAI;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,CAAC,CAAC;IACT,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,eAAe,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,cAAc,QAAQ,CAAC;AACpC,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAC1C,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAEvD,oBAAY,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,eAAe,CAAC;AAE7D,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,UAAU,CAAC,GAAG,oBAAoB,CAAC;IACvG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAAC;IAC7C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAAC;IAC3C,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC"}
package/out/types.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StorageTypeCustomEntity = exports.StorageTypeSecret = exports.StorageTypeKVS = void 0;
4
+ exports.StorageTypeKVS = 'kvs';
5
+ exports.StorageTypeSecret = 'secret';
6
+ exports.StorageTypeCustomEntity = 'custom_entity';
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@forge/storage-data-recovery",
3
+ "version": "2.0.0-next.0",
4
+ "description": "Forge Storage Data Recovery SDK",
5
+ "author": "Atlassian",
6
+ "license": "SEE LICENSE IN LICENSE.txt",
7
+ "main": "out/index.js",
8
+ "types": "out/index.d.ts",
9
+ "files": [
10
+ "out"
11
+ ],
12
+ "scripts": {
13
+ "build": "yarn run clean && yarn run compile",
14
+ "clean": "rm -rf ./out && rm -f tsconfig.tsbuildinfo",
15
+ "compile": "tsc -b -v"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "20.19.1"
19
+ },
20
+ "dependencies": {
21
+ "@forge/api": "6.1.5-next.1",
22
+ "@forge/kvs": "1.0.9-next.0"
23
+ },
24
+ "publishConfig": {
25
+ "registry": "https://packages.atlassian.com/api/npm/npm-public/"
26
+ }
27
+ }