firebase-functions 7.2.0 β 7.2.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/lib/common/utilities/path.js +1 -1
- package/lib/esm/common/utilities/path.mjs +1 -1
- package/lib/esm/params/types.mjs +25 -6
- package/lib/esm/v1/providers/firestore.mjs +4 -2
- package/lib/esm/v2/dataconnect.doc.mjs +13 -0
- package/lib/esm/v2/index.doc.mjs +2 -3
- package/lib/esm/v2/index.mjs +1 -1
- package/lib/params/types.d.ts +2 -2
- package/lib/params/types.js +25 -6
- package/lib/v1/providers/firestore.js +3 -1
- package/lib/v2/dataconnect.doc.d.ts +2 -0
- package/lib/v2/dataconnect.doc.js +26 -0
- package/lib/v2/index.doc.d.ts +15 -1
- package/lib/v2/index.doc.js +2 -9
- package/lib/v2/index.js +1 -1
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ function normalizePath(path) {
|
|
|
9
9
|
if (!path) {
|
|
10
10
|
return "";
|
|
11
11
|
}
|
|
12
|
-
return path.replace(/^\//, "").replace(/\/$/, "");
|
|
12
|
+
return path.replace(/^\//, "").replace(/\/$/, "").replace(/\/{2,}/g, "/");
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* Normalizes a given path and splits it into an array of segments.
|
|
@@ -8,7 +8,7 @@ function normalizePath(path) {
|
|
|
8
8
|
if (!path) {
|
|
9
9
|
return "";
|
|
10
10
|
}
|
|
11
|
-
return path.replace(/^\//, "").replace(/\/$/, "");
|
|
11
|
+
return path.replace(/^\//, "").replace(/\/$/, "").replace(/\/{2,}/g, "/");
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Normalizes a given path and splits it into an array of segments.
|
package/lib/esm/params/types.mjs
CHANGED
|
@@ -29,7 +29,7 @@ var Expression = class {
|
|
|
29
29
|
throw new Error("Not implemented");
|
|
30
30
|
}
|
|
31
31
|
/** Returns the expression's representation as a braced CEL expression. */
|
|
32
|
-
toCEL() {
|
|
32
|
+
toCEL(_transform = (a) => a) {
|
|
33
33
|
return `{{ ${this.toString()} }}`;
|
|
34
34
|
}
|
|
35
35
|
/** Returns the expression's representation as JSON. */
|
|
@@ -54,11 +54,30 @@ var InterpolationExpression = class extends Expression {
|
|
|
54
54
|
return result + str + val;
|
|
55
55
|
}, "");
|
|
56
56
|
}
|
|
57
|
-
toCEL() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
toCEL(transform$1 = (a) => a) {
|
|
58
|
+
const exprPlaceholders = [];
|
|
59
|
+
const PLACEHOLDER_PREFIX = "π€Ώπ€Ώπ€Ώπππ";
|
|
60
|
+
const PLACEHOLDER_SUFFIX = "ππππ€Ώπ€Ώπ€Ώ";
|
|
61
|
+
const rawString = this.strings.reduce((result, str, i) => {
|
|
62
|
+
if (i >= this.values.length) {
|
|
63
|
+
return result + str;
|
|
64
|
+
}
|
|
65
|
+
const val = this.values[i];
|
|
66
|
+
let valStr;
|
|
67
|
+
if (val instanceof Expression) {
|
|
68
|
+
valStr = `${PLACEHOLDER_PREFIX}${exprPlaceholders.length}${PLACEHOLDER_SUFFIX}`;
|
|
69
|
+
exprPlaceholders.push(val.toCEL());
|
|
70
|
+
} else {
|
|
71
|
+
valStr = String(val);
|
|
72
|
+
}
|
|
73
|
+
return result + str + valStr;
|
|
61
74
|
}, "");
|
|
75
|
+
let transformed = transform$1(rawString);
|
|
76
|
+
for (let i = 0; i < exprPlaceholders.length; i++) {
|
|
77
|
+
const placeholder = `${PLACEHOLDER_PREFIX}${i}${PLACEHOLDER_SUFFIX}`;
|
|
78
|
+
transformed = transformed.split(placeholder).join(exprPlaceholders[i]);
|
|
79
|
+
}
|
|
80
|
+
return transformed;
|
|
62
81
|
}
|
|
63
82
|
};
|
|
64
83
|
/** @internal */
|
|
@@ -72,7 +91,7 @@ var TransformedStringExpression = class extends Expression {
|
|
|
72
91
|
return this.transformer(valueOf(this.source));
|
|
73
92
|
}
|
|
74
93
|
toCEL() {
|
|
75
|
-
return this.source instanceof Expression ? this.source.toCEL() : this.transformer(this.source);
|
|
94
|
+
return this.source instanceof Expression ? this.source.toCEL(this.transformer) : this.transformer(this.source);
|
|
76
95
|
}
|
|
77
96
|
};
|
|
78
97
|
function valueOf(arg) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { __export } from "../../_virtual/rolldown_runtime.mjs";
|
|
2
|
-
import { CompareExpression, Expression } from "../../params/types.mjs";
|
|
2
|
+
import { CompareExpression, Expression, transform } from "../../params/types.mjs";
|
|
3
3
|
import { expr, projectID } from "../../params/index.mjs";
|
|
4
4
|
import { Change } from "../../common/change.mjs";
|
|
5
5
|
import { makeCloudFunction } from "../cloud-functions.mjs";
|
|
6
|
+
import { normalizePath } from "../../common/utilities/path.mjs";
|
|
6
7
|
import { createBeforeSnapshotFromJson, createSnapshotFromJson } from "../../common/providers/firestore.mjs";
|
|
7
8
|
|
|
8
9
|
//#region src/v1/providers/firestore.ts
|
|
@@ -75,6 +76,7 @@ var NamespaceBuilder = class {
|
|
|
75
76
|
this.namespace = namespace$1;
|
|
76
77
|
}
|
|
77
78
|
document(path) {
|
|
79
|
+
const normalized = transform(path, normalizePath);
|
|
78
80
|
const triggerResource = () => {
|
|
79
81
|
if (!process.env.GCLOUD_PROJECT) {
|
|
80
82
|
throw new Error("process.env.GCLOUD_PROJECT is not set.");
|
|
@@ -89,7 +91,7 @@ var NamespaceBuilder = class {
|
|
|
89
91
|
} else if (this.namespace) {
|
|
90
92
|
nsPart = `@${this.namespace}`;
|
|
91
93
|
}
|
|
92
|
-
return expr`projects/${project}/databases/${this.database}/documents${nsPart}/${
|
|
94
|
+
return expr`projects/${project}/databases/${this.database}/documents${nsPart}/${normalized}`;
|
|
93
95
|
};
|
|
94
96
|
return new DocumentBuilder(triggerResource, this.options);
|
|
95
97
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { __export } from "../_virtual/rolldown_runtime.mjs";
|
|
2
|
+
import { mutationExecutedEventType, onMutationExecuted } from "./providers/dataconnect/index.mjs";
|
|
3
|
+
import { graphql_exports } from "./providers/dataconnect/graphql.mjs";
|
|
4
|
+
|
|
5
|
+
//#region src/v2/dataconnect.doc.ts
|
|
6
|
+
var dataconnect_doc_exports = /* @__PURE__ */ __export({
|
|
7
|
+
graphql: () => graphql_exports,
|
|
8
|
+
mutationExecutedEventType: () => mutationExecutedEventType,
|
|
9
|
+
onMutationExecuted: () => onMutationExecuted
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
export { dataconnect_doc_exports, graphql_exports as graphql, mutationExecutedEventType, onMutationExecuted };
|
package/lib/esm/v2/index.doc.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { onInit } from "../common/onInit.mjs";
|
|
|
6
6
|
import { config } from "../v1/config.mjs";
|
|
7
7
|
import { setGlobalOptions } from "./options.mjs";
|
|
8
8
|
import { pubsub_exports } from "./providers/pubsub.mjs";
|
|
9
|
+
import { dataconnect_doc_exports } from "./dataconnect.doc.mjs";
|
|
9
10
|
import { alerts_exports } from "./providers/alerts/index.mjs";
|
|
10
11
|
import { database_exports } from "./providers/database.mjs";
|
|
11
12
|
import { eventarc_exports } from "./providers/eventarc.mjs";
|
|
@@ -17,8 +18,6 @@ import { tasks_exports } from "./providers/tasks.mjs";
|
|
|
17
18
|
import { remoteConfig_exports } from "./providers/remoteConfig.mjs";
|
|
18
19
|
import { testLab_exports } from "./providers/testLab.mjs";
|
|
19
20
|
import { firestore_exports } from "./providers/firestore.mjs";
|
|
20
|
-
import { dataconnect_exports } from "./providers/dataconnect/index.mjs";
|
|
21
21
|
import { app } from "./index.mjs";
|
|
22
|
-
import { graphql_exports } from "./providers/dataconnect/graphql.mjs";
|
|
23
22
|
|
|
24
|
-
export { Change, alerts_exports as alerts, app, config, database_exports as database,
|
|
23
|
+
export { Change, alerts_exports as alerts, app, config, database_exports as database, dataconnect_doc_exports as dataconnect, eventarc_exports as eventarc, firestore_exports as firestore, https_exports as https, identity_exports as identity, logger, onInit, params_exports as params, pubsub_exports as pubsub, remoteConfig_exports as remoteConfig, scheduler_exports as scheduler, setGlobalOptions, storage_exports as storage, tasks_exports as tasks, testLab_exports as testLab, traceContext };
|
package/lib/esm/v2/index.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import { config } from "../v1/config.mjs";
|
|
|
8
8
|
import { setGlobalOptions } from "./options.mjs";
|
|
9
9
|
import { pubsub_exports } from "./providers/pubsub.mjs";
|
|
10
10
|
import "./core.mjs";
|
|
11
|
+
import { dataconnect_exports } from "./providers/dataconnect/index.mjs";
|
|
11
12
|
import { alerts_exports } from "./providers/alerts/index.mjs";
|
|
12
13
|
import { database_exports } from "./providers/database.mjs";
|
|
13
14
|
import { eventarc_exports } from "./providers/eventarc.mjs";
|
|
@@ -19,7 +20,6 @@ import { tasks_exports } from "./providers/tasks.mjs";
|
|
|
19
20
|
import { remoteConfig_exports } from "./providers/remoteConfig.mjs";
|
|
20
21
|
import { testLab_exports } from "./providers/testLab.mjs";
|
|
21
22
|
import { firestore_exports } from "./providers/firestore.mjs";
|
|
22
|
-
import { dataconnect_exports } from "./providers/dataconnect/index.mjs";
|
|
23
23
|
|
|
24
24
|
//#region src/v2/index.ts
|
|
25
25
|
const app = { setEmulatedAdminApp: setApp };
|
package/lib/params/types.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare abstract class Expression<T extends string | number | boolean | s
|
|
|
11
11
|
/** Returns the expression's runtime value, based on the CLI's resolution of parameters. */
|
|
12
12
|
value(): T;
|
|
13
13
|
/** Returns the expression's representation as a braced CEL expression. */
|
|
14
|
-
toCEL(): string;
|
|
14
|
+
toCEL(_transform?: (val: string) => string): string;
|
|
15
15
|
/** Returns the expression's representation as JSON. */
|
|
16
16
|
toJSON(): string;
|
|
17
17
|
}
|
|
@@ -23,7 +23,7 @@ export declare class InterpolationExpression extends Expression<string> {
|
|
|
23
23
|
private strings;
|
|
24
24
|
private values;
|
|
25
25
|
constructor(strings: TemplateStringsArray, values: (string | Expression<any>)[]);
|
|
26
|
-
toCEL(): string;
|
|
26
|
+
toCEL(transform?: (val: string) => string): string;
|
|
27
27
|
}
|
|
28
28
|
export declare function valueOf<T extends string | number | boolean | string[]>(arg: T | Expression<T>): T;
|
|
29
29
|
export declare function celOf<T extends string | number | boolean | string[]>(arg: T | Expression<T>): T | string;
|
package/lib/params/types.js
CHANGED
|
@@ -29,7 +29,7 @@ var Expression = class {
|
|
|
29
29
|
throw new Error("Not implemented");
|
|
30
30
|
}
|
|
31
31
|
/** Returns the expression's representation as a braced CEL expression. */
|
|
32
|
-
toCEL() {
|
|
32
|
+
toCEL(_transform = (a) => a) {
|
|
33
33
|
return `{{ ${this.toString()} }}`;
|
|
34
34
|
}
|
|
35
35
|
/** Returns the expression's representation as JSON. */
|
|
@@ -54,11 +54,30 @@ var InterpolationExpression = class extends Expression {
|
|
|
54
54
|
return result + str + val;
|
|
55
55
|
}, "");
|
|
56
56
|
}
|
|
57
|
-
toCEL() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
toCEL(transform$1 = (a) => a) {
|
|
58
|
+
const exprPlaceholders = [];
|
|
59
|
+
const PLACEHOLDER_PREFIX = "π€Ώπ€Ώπ€Ώπππ";
|
|
60
|
+
const PLACEHOLDER_SUFFIX = "ππππ€Ώπ€Ώπ€Ώ";
|
|
61
|
+
const rawString = this.strings.reduce((result, str, i) => {
|
|
62
|
+
if (i >= this.values.length) {
|
|
63
|
+
return result + str;
|
|
64
|
+
}
|
|
65
|
+
const val = this.values[i];
|
|
66
|
+
let valStr;
|
|
67
|
+
if (val instanceof Expression) {
|
|
68
|
+
valStr = `${PLACEHOLDER_PREFIX}${exprPlaceholders.length}${PLACEHOLDER_SUFFIX}`;
|
|
69
|
+
exprPlaceholders.push(val.toCEL());
|
|
70
|
+
} else {
|
|
71
|
+
valStr = String(val);
|
|
72
|
+
}
|
|
73
|
+
return result + str + valStr;
|
|
61
74
|
}, "");
|
|
75
|
+
let transformed = transform$1(rawString);
|
|
76
|
+
for (let i = 0; i < exprPlaceholders.length; i++) {
|
|
77
|
+
const placeholder = `${PLACEHOLDER_PREFIX}${i}${PLACEHOLDER_SUFFIX}`;
|
|
78
|
+
transformed = transformed.split(placeholder).join(exprPlaceholders[i]);
|
|
79
|
+
}
|
|
80
|
+
return transformed;
|
|
62
81
|
}
|
|
63
82
|
};
|
|
64
83
|
/** @internal */
|
|
@@ -72,7 +91,7 @@ var TransformedStringExpression = class extends Expression {
|
|
|
72
91
|
return this.transformer(valueOf(this.source));
|
|
73
92
|
}
|
|
74
93
|
toCEL() {
|
|
75
|
-
return this.source instanceof Expression ? this.source.toCEL() : this.transformer(this.source);
|
|
94
|
+
return this.source instanceof Expression ? this.source.toCEL(this.transformer) : this.transformer(this.source);
|
|
76
95
|
}
|
|
77
96
|
};
|
|
78
97
|
function valueOf(arg) {
|
|
@@ -3,6 +3,7 @@ const require_params_types = require('../../params/types.js');
|
|
|
3
3
|
const require_params_index = require('../../params/index.js');
|
|
4
4
|
const require_common_change = require('../../common/change.js');
|
|
5
5
|
const require_v1_cloud_functions = require('../cloud-functions.js');
|
|
6
|
+
const require_common_utilities_path = require('../../common/utilities/path.js');
|
|
6
7
|
const require_common_providers_firestore = require('../../common/providers/firestore.js');
|
|
7
8
|
|
|
8
9
|
//#region src/v1/providers/firestore.ts
|
|
@@ -75,6 +76,7 @@ var NamespaceBuilder = class {
|
|
|
75
76
|
this.namespace = namespace$1;
|
|
76
77
|
}
|
|
77
78
|
document(path) {
|
|
79
|
+
const normalized = require_params_types.transform(path, require_common_utilities_path.normalizePath);
|
|
78
80
|
const triggerResource = () => {
|
|
79
81
|
if (!process.env.GCLOUD_PROJECT) {
|
|
80
82
|
throw new Error("process.env.GCLOUD_PROJECT is not set.");
|
|
@@ -89,7 +91,7 @@ var NamespaceBuilder = class {
|
|
|
89
91
|
} else if (this.namespace) {
|
|
90
92
|
nsPart = `@${this.namespace}`;
|
|
91
93
|
}
|
|
92
|
-
return require_params_index.expr`projects/${project}/databases/${this.database}/documents${nsPart}/${
|
|
94
|
+
return require_params_index.expr`projects/${project}/databases/${this.database}/documents${nsPart}/${normalized}`;
|
|
93
95
|
};
|
|
94
96
|
return new DocumentBuilder(triggerResource, this.options);
|
|
95
97
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.js');
|
|
2
|
+
const require_v2_providers_dataconnect_index = require('./providers/dataconnect/index.js');
|
|
3
|
+
const require_v2_providers_dataconnect_graphql = require('./providers/dataconnect/graphql.js');
|
|
4
|
+
|
|
5
|
+
//#region src/v2/dataconnect.doc.ts
|
|
6
|
+
var dataconnect_doc_exports = /* @__PURE__ */ require_rolldown_runtime.__export({
|
|
7
|
+
graphql: () => require_v2_providers_dataconnect_graphql.graphql_exports,
|
|
8
|
+
mutationExecutedEventType: () => require_v2_providers_dataconnect_index.mutationExecutedEventType,
|
|
9
|
+
onMutationExecuted: () => require_v2_providers_dataconnect_index.onMutationExecuted
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
Object.defineProperty(exports, 'dataconnect_doc_exports', {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () {
|
|
16
|
+
return dataconnect_doc_exports;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, 'graphql', {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () {
|
|
22
|
+
return require_v2_providers_dataconnect_graphql.graphql_exports;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
exports.mutationExecutedEventType = require_v2_providers_dataconnect_index.mutationExecutedEventType;
|
|
26
|
+
exports.onMutationExecuted = require_v2_providers_dataconnect_index.onMutationExecuted;
|
package/lib/v2/index.doc.d.ts
CHANGED
|
@@ -1 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @internal
|
|
3
|
+
* Documentation-only entry point. This file is not part of the public API
|
|
4
|
+
* and is used only by api-extractor to generate reference documentation.
|
|
5
|
+
* It includes exports that are not part of the main `index.ts` entry point
|
|
6
|
+
* to avoid forcing optional peer dependencies on all users.
|
|
7
|
+
*
|
|
8
|
+
* DO NOT use for runtime imports.
|
|
9
|
+
* The 2nd gen API for Cloud Functions for Firebase.
|
|
10
|
+
* This SDK supports deep imports. For example, the namespace
|
|
11
|
+
* `pubsub` is available at `firebase-functions/v2` or is directly importable
|
|
12
|
+
* from `firebase-functions/v2/pubsub`.
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
export * as dataconnect from "./dataconnect.doc";
|
package/lib/v2/index.doc.js
CHANGED
|
@@ -6,6 +6,7 @@ const require_common_onInit = require('../common/onInit.js');
|
|
|
6
6
|
const require_v1_config = require('../v1/config.js');
|
|
7
7
|
const require_v2_options = require('./options.js');
|
|
8
8
|
const require_v2_providers_pubsub = require('./providers/pubsub.js');
|
|
9
|
+
const require_v2_dataconnect_doc = require('./dataconnect.doc.js');
|
|
9
10
|
const require_v2_providers_alerts_index = require('./providers/alerts/index.js');
|
|
10
11
|
const require_v2_providers_database = require('./providers/database.js');
|
|
11
12
|
const require_v2_providers_eventarc = require('./providers/eventarc.js');
|
|
@@ -17,9 +18,7 @@ const require_v2_providers_tasks = require('./providers/tasks.js');
|
|
|
17
18
|
const require_v2_providers_remoteConfig = require('./providers/remoteConfig.js');
|
|
18
19
|
const require_v2_providers_testLab = require('./providers/testLab.js');
|
|
19
20
|
const require_v2_providers_firestore = require('./providers/firestore.js');
|
|
20
|
-
const require_v2_providers_dataconnect_index = require('./providers/dataconnect/index.js');
|
|
21
21
|
const require_v2_index = require('./index.js');
|
|
22
|
-
const require_v2_providers_dataconnect_graphql = require('./providers/dataconnect/graphql.js');
|
|
23
22
|
|
|
24
23
|
exports.Change = require_common_change.Change;
|
|
25
24
|
Object.defineProperty(exports, 'alerts', {
|
|
@@ -39,7 +38,7 @@ Object.defineProperty(exports, 'database', {
|
|
|
39
38
|
Object.defineProperty(exports, 'dataconnect', {
|
|
40
39
|
enumerable: true,
|
|
41
40
|
get: function () {
|
|
42
|
-
return
|
|
41
|
+
return require_v2_dataconnect_doc.dataconnect_doc_exports;
|
|
43
42
|
}
|
|
44
43
|
});
|
|
45
44
|
Object.defineProperty(exports, 'eventarc', {
|
|
@@ -54,12 +53,6 @@ Object.defineProperty(exports, 'firestore', {
|
|
|
54
53
|
return require_v2_providers_firestore.firestore_exports;
|
|
55
54
|
}
|
|
56
55
|
});
|
|
57
|
-
Object.defineProperty(exports, 'graphql', {
|
|
58
|
-
enumerable: true,
|
|
59
|
-
get: function () {
|
|
60
|
-
return require_v2_providers_dataconnect_graphql.graphql_exports;
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
56
|
Object.defineProperty(exports, 'https', {
|
|
64
57
|
enumerable: true,
|
|
65
58
|
get: function () {
|
package/lib/v2/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const require_v1_config = require('../v1/config.js');
|
|
|
8
8
|
const require_v2_options = require('./options.js');
|
|
9
9
|
const require_v2_providers_pubsub = require('./providers/pubsub.js');
|
|
10
10
|
require('./core.js');
|
|
11
|
+
const require_v2_providers_dataconnect_index = require('./providers/dataconnect/index.js');
|
|
11
12
|
const require_v2_providers_alerts_index = require('./providers/alerts/index.js');
|
|
12
13
|
const require_v2_providers_database = require('./providers/database.js');
|
|
13
14
|
const require_v2_providers_eventarc = require('./providers/eventarc.js');
|
|
@@ -19,7 +20,6 @@ const require_v2_providers_tasks = require('./providers/tasks.js');
|
|
|
19
20
|
const require_v2_providers_remoteConfig = require('./providers/remoteConfig.js');
|
|
20
21
|
const require_v2_providers_testLab = require('./providers/testLab.js');
|
|
21
22
|
const require_v2_providers_firestore = require('./providers/firestore.js');
|
|
22
|
-
const require_v2_providers_dataconnect_index = require('./providers/dataconnect/index.js');
|
|
23
23
|
|
|
24
24
|
//#region src/v2/index.ts
|
|
25
25
|
const app = { setEmulatedAdminApp: require_common_app.setApp };
|