@fluidframework/driver-utils 0.49.1 → 0.50.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/driver-utils",
3
- "version": "0.49.1",
3
+ "version": "0.50.0",
4
4
  "description": "Collection of utility functions for Fluid drivers",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": "https://github.com/microsoft/FluidFramework",
@@ -57,20 +57,20 @@
57
57
  "dependencies": {
58
58
  "@fluidframework/common-definitions": "^0.20.1",
59
59
  "@fluidframework/common-utils": "^0.32.1",
60
- "@fluidframework/core-interfaces": "^0.39.7",
61
- "@fluidframework/driver-definitions": "^0.40.0",
62
- "@fluidframework/gitresources": "^0.1032.0",
63
- "@fluidframework/protocol-base": "^0.1032.0",
60
+ "@fluidframework/core-interfaces": "^0.40.0",
61
+ "@fluidframework/driver-definitions": "^0.41.0",
62
+ "@fluidframework/gitresources": "^0.1033.0",
63
+ "@fluidframework/protocol-base": "^0.1033.0",
64
64
  "@fluidframework/protocol-definitions": "^0.1025.0",
65
- "@fluidframework/telemetry-utils": "^0.49.1",
65
+ "@fluidframework/telemetry-utils": "^0.50.0",
66
66
  "axios": "^0.21.1",
67
67
  "uuid": "^8.3.1"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@fluidframework/build-common": "^0.23.0",
71
71
  "@fluidframework/eslint-config-fluid": "^0.23.0",
72
- "@fluidframework/mocha-test-setup": "^0.49.1",
73
- "@fluidframework/runtime-utils": "^0.49.1",
72
+ "@fluidframework/mocha-test-setup": "^0.50.0",
73
+ "@fluidframework/runtime-utils": "^0.50.0",
74
74
  "@microsoft/api-extractor": "^7.16.1",
75
75
  "@types/mocha": "^8.2.2",
76
76
  "@types/node": "^12.19.0",
@@ -44,14 +44,9 @@ export class InsecureUrlResolver implements IUrlResolver {
44
44
  // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
45
45
  if (request.headers?.[DriverHeader.createNew]) {
46
46
  const [, queryString] = request.url.split("?");
47
-
48
47
  const searchParams = new URLSearchParams(queryString);
49
48
  const fileName = searchParams.get("fileName");
50
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
51
- if (!fileName) {
52
- throw new Error("FileName should be there!!");
53
- }
54
- return this.resolveHelper(fileName, "");
49
+ return this.resolveHelper(fileName);
55
50
  }
56
51
  const parsedUrl = new URL(request.url);
57
52
  // If hosts match then we use the local tenant information. Otherwise we make a REST call out to the hosting
@@ -88,10 +83,28 @@ export class InsecureUrlResolver implements IUrlResolver {
88
83
  }
89
84
  }
90
85
 
91
- private resolveHelper(documentId: string, documentRelativePath: string, queryParams: string = "") {
86
+ private resolveHelper(documentId: string | null, documentRelativePath: string = "", queryParams: string = "") {
92
87
  const encodedTenantId = encodeURIComponent(this.tenantId);
93
- const encodedDocId = encodeURIComponent(documentId);
94
88
  const host = new URL(this.ordererUrl).host;
89
+ // when the document ID is not provided we need to resolve a special create new document URL.
90
+ // the actual container ID will be generated by the driver.
91
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
92
+ if (!documentId) {
93
+ const createNewResponse: IFluidResolvedUrl = {
94
+ endpoints: {
95
+ deltaStorageUrl: `${this.ordererUrl}/deltas/${encodedTenantId}/new`,
96
+ ordererUrl: this.ordererUrl,
97
+ storageUrl: `${this.storageUrl}/repos/${encodedTenantId}`,
98
+ },
99
+ // document ID is ignored by the driver for new container requests
100
+ id: "",
101
+ tokens: {},
102
+ type: "fluid",
103
+ url: `fluid://${host}/${encodedTenantId}/new`,
104
+ };
105
+ return createNewResponse;
106
+ }
107
+ const encodedDocId = encodeURIComponent(documentId);
95
108
  const relativePath = !documentRelativePath || documentRelativePath.startsWith("/")
96
109
  ? documentRelativePath : `/${documentRelativePath}`;
97
110
  const documentUrl = `fluid://${host}/${encodedTenantId}/${encodedDocId}${relativePath}${queryParams}`;
@@ -117,7 +130,7 @@ export class InsecureUrlResolver implements IUrlResolver {
117
130
  const fluidResolvedUrl = resolvedUrl as IFluidResolvedUrl;
118
131
 
119
132
  const parsedUrl = parse(fluidResolvedUrl.url);
120
- const [, , documentId] = parsedUrl.pathname?.split("/");
133
+ const [, , documentId] = parsedUrl.pathname?.split("/") ?? [];
121
134
  // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
122
135
  assert(!!documentId, 0x273 /* "Invalid document id from parsed URL" */);
123
136
 
@@ -130,9 +143,10 @@ export class InsecureUrlResolver implements IUrlResolver {
130
143
  this.tenantId)}/${encodeURIComponent(documentId)}/${url}`;
131
144
  }
132
145
 
133
- public createCreateNewRequest(fileName: string): IRequest {
146
+ public createCreateNewRequest(fileName?: string): IRequest {
134
147
  const createNewRequest: IRequest = {
135
- url: `${this.hostUrl}?fileName=${fileName}`,
148
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
149
+ url: fileName ? `${this.hostUrl}?fileName=${fileName}` : this.hostUrl,
136
150
  headers: {
137
151
  [DriverHeader.createNew]: true,
138
152
  },
package/src/network.ts CHANGED
@@ -37,10 +37,11 @@ export class GenericNetworkError extends LoggingError implements IDriverErrorBas
37
37
 
38
38
  constructor(
39
39
  readonly fluidErrorCode: string,
40
+ message: string,
40
41
  readonly canRetry: boolean,
41
42
  props?: ITelemetryProperties,
42
43
  ) {
43
- super(fluidErrorCode, props);
44
+ super(message, props);
44
45
  }
45
46
  }
46
47
 
@@ -67,46 +68,51 @@ export class AuthorizationError extends LoggingError implements IAuthorizationEr
67
68
 
68
69
  constructor(
69
70
  readonly fluidErrorCode: string,
71
+ message: string,
70
72
  readonly claims: string | undefined,
71
73
  readonly tenantId: string | undefined,
72
74
  props?: ITelemetryProperties,
73
75
  ) {
74
76
  // don't log claims or tenantId
75
- super(fluidErrorCode, props, new Set(["claims", "tenantId"]));
77
+ super(message, props, new Set(["claims", "tenantId"]));
76
78
  }
77
79
  }
78
80
 
79
81
  export class NetworkErrorBasic<T extends string> extends LoggingError implements IFluidErrorBase {
80
82
  constructor(
81
83
  readonly fluidErrorCode: string,
84
+ message: string,
82
85
  readonly errorType: T,
83
86
  readonly canRetry: boolean,
84
87
  props?: ITelemetryProperties,
85
88
  ) {
86
- super(fluidErrorCode, props);
89
+ super(message, props);
87
90
  }
88
91
  }
89
92
 
90
93
  export class NonRetryableError<T extends string> extends NetworkErrorBasic<T> {
91
94
  constructor(
92
95
  fluidErrorCode: string,
96
+ message: string | undefined,
93
97
  readonly errorType: T,
94
98
  props?: ITelemetryProperties,
95
99
  ) {
96
- super(fluidErrorCode, errorType, false, props);
100
+ super(fluidErrorCode, message ?? fluidErrorCode, errorType, false, props);
97
101
  }
98
102
  }
99
103
 
100
104
  export class RetryableError<T extends string> extends NetworkErrorBasic<T> {
101
105
  constructor(
102
106
  fluidErrorCode: string,
107
+ message: string | undefined,
103
108
  readonly errorType: T,
104
109
  props?: ITelemetryProperties,
105
110
  ) {
106
- super(fluidErrorCode, errorType, true, props);
111
+ super(fluidErrorCode, message ?? fluidErrorCode, errorType, true, props);
107
112
  }
108
113
  }
109
114
 
115
+ //* Check
110
116
  /**
111
117
  * Throttling error class - used to communicate all throttling errors
112
118
  */
@@ -116,26 +122,28 @@ export class ThrottlingError extends LoggingError implements IThrottlingWarning,
116
122
 
117
123
  constructor(
118
124
  readonly fluidErrorCode: string,
125
+ message: string,
119
126
  readonly retryAfterSeconds: number,
120
127
  props?: ITelemetryProperties,
121
128
  ) {
122
- super(fluidErrorCode, props);
129
+ super(message, props);
123
130
  }
124
131
  }
125
132
 
126
- export const createWriteError = (errorMessage: string) =>
127
- new NonRetryableError(errorMessage, DriverErrorType.writeError);
133
+ export const createWriteError = (fluidErrorCode: string) =>
134
+ new NonRetryableError(fluidErrorCode, undefined, DriverErrorType.writeError);
128
135
 
129
136
  export function createGenericNetworkError(
130
137
  fluidErrorCode: string,
138
+ message: string | undefined,
131
139
  canRetry: boolean,
132
140
  retryAfterMs?: number,
133
141
  props?: ITelemetryProperties,
134
142
  ): ThrottlingError | GenericNetworkError {
135
143
  if (retryAfterMs !== undefined && canRetry) {
136
- return new ThrottlingError(fluidErrorCode, retryAfterMs / 1000, props);
144
+ return new ThrottlingError(fluidErrorCode, message ?? fluidErrorCode, retryAfterMs / 1000, props);
137
145
  }
138
- return new GenericNetworkError(fluidErrorCode, canRetry, props);
146
+ return new GenericNetworkError(fluidErrorCode, message ?? fluidErrorCode, canRetry, props);
139
147
  }
140
148
 
141
149
  /**
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/driver-utils";
9
- export const pkgVersion = "0.49.1";
9
+ export const pkgVersion = "0.50.0";
@@ -400,6 +400,7 @@ async function getSingleOpBatch(
400
400
  // current as it can't get ops.
401
401
  throw createGenericNetworkError(
402
402
  "failedToRetrieveOpsFromStorage:TooManyRetries",
403
+ undefined,
403
404
  false /* canRetry */,
404
405
  undefined /* retryAfterSeconds */,
405
406
  {
@@ -37,7 +37,7 @@ export async function runWithRetry<T>(
37
37
  // If it is not retriable, then just throw the error.
38
38
  if (!canRetryOnError(err)) {
39
39
  logger.sendErrorEvent({
40
- eventName: fetchCallName,
40
+ eventName: `${fetchCallName}_cancel`,
41
41
  retry: numRetries,
42
42
  duration: performance.now() - startTime,
43
43
  }, err);
@@ -57,7 +57,7 @@ export async function runWithRetry<T>(
57
57
  } while (!success);
58
58
  if (numRetries > 0) {
59
59
  logger.sendTelemetryEvent({
60
- eventName: fetchCallName,
60
+ eventName: `${fetchCallName}_lastError`,
61
61
  retry: numRetries,
62
62
  duration: performance.now() - startTime,
63
63
  },