firebase-tools 14.14.0 → 14.15.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/apphosting/backend.js +40 -15
- package/lib/auth.js +37 -2
- package/lib/command.js +19 -5
- package/lib/commands/apphosting-backends-create.js +8 -5
- package/lib/commands/dataconnect-sdk-generate.js +3 -5
- package/lib/commands/dataconnect-sql-diff.js +2 -2
- package/lib/commands/dataconnect-sql-grant.js +2 -2
- package/lib/commands/dataconnect-sql-migrate.js +2 -2
- package/lib/commands/dataconnect-sql-setup.js +2 -2
- package/lib/commands/dataconnect-sql-shell.js +2 -2
- package/lib/commands/init.js +11 -0
- package/lib/commands/login.js +12 -7
- package/lib/crashlytics/addNote.js +27 -0
- package/lib/crashlytics/deleteNote.js +23 -0
- package/lib/crashlytics/getIssueDetails.js +5 -20
- package/lib/crashlytics/getSampleCrash.js +6 -20
- package/lib/crashlytics/listNotes.js +29 -0
- package/lib/crashlytics/listTopDevices.js +33 -0
- package/lib/crashlytics/listTopIssues.js +8 -23
- package/lib/crashlytics/listTopOperatingSystems.js +32 -0
- package/lib/crashlytics/listTopVersions.js +32 -0
- package/lib/crashlytics/updateIssue.js +35 -0
- package/lib/crashlytics/utils.js +38 -0
- package/lib/dataconnect/appFinder.js +103 -0
- package/lib/dataconnect/load.js +105 -6
- package/lib/deploy/dataconnect/prepare.js +1 -3
- package/lib/emulator/controller.js +2 -2
- package/lib/emulator/downloadableEmulatorInfo.json +17 -17
- package/lib/experiments.js +5 -0
- package/lib/init/features/dataconnect/create_app.js +48 -0
- package/lib/init/features/dataconnect/index.js +19 -45
- package/lib/init/features/dataconnect/sdk.js +218 -161
- package/lib/init/features/index.js +3 -3
- package/lib/init/index.js +5 -2
- package/lib/management/apps.js +3 -3
- package/lib/mcp/prompts/core/deploy.js +51 -8
- package/lib/mcp/prompts/crashlytics/common.js +10 -0
- package/lib/mcp/prompts/crashlytics/fix_issue.js +89 -0
- package/lib/mcp/prompts/crashlytics/index.js +6 -0
- package/lib/mcp/prompts/crashlytics/prioritize_issues.js +79 -0
- package/lib/mcp/prompts/dataconnect/index.js +9 -0
- package/lib/mcp/prompts/dataconnect/schema.js +68 -0
- package/lib/mcp/prompts/index.js +5 -3
- package/lib/mcp/tools/core/init.js +16 -3
- package/lib/mcp/tools/crashlytics/add_note.js +32 -0
- package/lib/mcp/tools/crashlytics/constants.js +11 -0
- package/lib/mcp/tools/crashlytics/delete_note.js +35 -0
- package/lib/mcp/tools/crashlytics/get_issue_details.js +2 -4
- package/lib/mcp/tools/crashlytics/get_sample_crash.js +4 -4
- package/lib/mcp/tools/crashlytics/index.js +16 -2
- package/lib/mcp/tools/crashlytics/list_notes.js +37 -0
- package/lib/mcp/tools/crashlytics/list_top_devices.js +33 -0
- package/lib/mcp/tools/crashlytics/list_top_issues.js +5 -7
- package/lib/mcp/tools/crashlytics/list_top_operating_systems.js +33 -0
- package/lib/mcp/tools/crashlytics/list_top_versions.js +33 -0
- package/lib/mcp/tools/crashlytics/update_issue.js +37 -0
- package/lib/mcp/tools/dataconnect/compile.js +43 -0
- package/lib/mcp/tools/dataconnect/execute_graphql.js +4 -4
- package/lib/mcp/tools/dataconnect/execute_graphql_read.js +4 -4
- package/lib/mcp/tools/dataconnect/execute_mutation.js +4 -4
- package/lib/mcp/tools/dataconnect/execute_query.js +4 -4
- package/lib/mcp/tools/dataconnect/generate_operation.js +2 -2
- package/lib/mcp/tools/dataconnect/get_connector.js +3 -3
- package/lib/mcp/tools/dataconnect/get_schema.js +3 -3
- package/lib/mcp/tools/dataconnect/index.js +2 -0
- package/lib/mcp/tools/firestore/list_collections.js +0 -3
- package/lib/mcp/tools/index.js +3 -0
- package/lib/mcp/util/dataconnect/compile.js +18 -0
- package/lib/mcp/util/dataconnect/content.js +655 -0
- package/lib/utils.js +11 -1
- package/package.json +1 -1
- package/templates/init/dataconnect/connector.yaml +0 -16
- package/templates/init/dataconnect/dataconnect.yaml +2 -1
- package/templates/init/dataconnect/mutations.gql +29 -29
- package/templates/init/dataconnect/queries.gql +73 -73
- package/templates/init/dataconnect/schema.gql +48 -48
- package/lib/dataconnect/fileUtils.js +0 -168
- /package/lib/mcp/{tools → util}/dataconnect/converter.js +0 -0
- /package/lib/mcp/{tools → util}/dataconnect/emulator.js +0 -0
|
@@ -8,5 +8,6 @@ schema:
|
|
|
8
8
|
database: __cloudSqlDatabase__
|
|
9
9
|
cloudSql:
|
|
10
10
|
instanceId: __cloudSqlInstanceId__
|
|
11
|
-
|
|
11
|
+
# schemaValidation: "STRICT" # STRICT mode makes Postgres schema match Data Connect exactly.
|
|
12
|
+
# schemaValidation: "COMPATIBLE" # COMPATIBLE mode makes Postgres schema compatible with Data Connect.
|
|
12
13
|
connectorDirs: __connectorDirs__
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Example mutations for a simple movie app
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
# Create a movie based on user input
|
|
4
|
+
mutation CreateMovie($title: String!, $genre: String!, $imageUrl: String!)
|
|
5
|
+
@auth(level: USER_EMAIL_VERIFIED, insecureReason: "Any email verified users can create a new movie.") {
|
|
6
|
+
movie_insert(data: { title: $title, genre: $genre, imageUrl: $imageUrl })
|
|
7
|
+
}
|
|
8
8
|
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
# Upsert (update or insert) a user's username based on their auth.uid
|
|
10
|
+
mutation UpsertUser($username: String!) @auth(level: USER) {
|
|
11
|
+
# The "auth.uid" server value ensures that users can only register their own user.
|
|
12
|
+
user_upsert(data: { id_expr: "auth.uid", username: $username })
|
|
13
|
+
}
|
|
14
14
|
|
|
15
|
-
#
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
15
|
+
# Add a review for a movie
|
|
16
|
+
mutation AddReview($movieId: UUID!, $rating: Int!, $reviewText: String!)
|
|
17
|
+
@auth(level: USER) {
|
|
18
|
+
review_upsert(
|
|
19
|
+
data: {
|
|
20
|
+
userId_expr: "auth.uid"
|
|
21
|
+
movieId: $movieId
|
|
22
|
+
rating: $rating
|
|
23
|
+
reviewText: $reviewText
|
|
24
|
+
# reviewDate defaults to today in the schema. No need to set it manually.
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
28
|
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
# Logged in user can delete their review for a movie
|
|
30
|
+
mutation DeleteReview($movieId: UUID!) @auth(level: USER) {
|
|
31
|
+
# The "auth.uid" server value ensures that users can only delete their own reviews.
|
|
32
|
+
review_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
|
|
33
|
+
}
|
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Example queries for a simple movie app.
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
# @auth() directives control who can call each operation.
|
|
4
|
+
# Anyone should be able to list all movies, so the auth level is set to PUBLIC
|
|
5
|
+
query ListMovies @auth(level: PUBLIC, insecureReason: "Anyone can list all movies.") {
|
|
6
|
+
movies {
|
|
7
|
+
id
|
|
8
|
+
title
|
|
9
|
+
imageUrl
|
|
10
|
+
genre
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
13
|
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
# List all users, only admins should be able to list all users, so we use NO_ACCESS
|
|
15
|
+
query ListUsers @auth(level: NO_ACCESS) {
|
|
16
|
+
users {
|
|
17
|
+
id
|
|
18
|
+
username
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
22
|
+
# Logged in users can list all their reviews and movie titles associated with the review
|
|
23
|
+
# Since the query uses the uid of the current authenticated user, we set auth level to USER
|
|
24
|
+
query ListUserReviews @auth(level: USER) {
|
|
25
|
+
user(key: { id_expr: "auth.uid" }) {
|
|
26
|
+
id
|
|
27
|
+
username
|
|
28
|
+
# <field>_on_<foreign_key_field> makes it easy to grab info from another table
|
|
29
|
+
# Here, we use it to grab all the reviews written by the user.
|
|
30
|
+
reviews: reviews_on_user {
|
|
31
|
+
rating
|
|
32
|
+
reviewDate
|
|
33
|
+
reviewText
|
|
34
|
+
movie {
|
|
35
|
+
id
|
|
36
|
+
title
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
41
|
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
42
|
+
# Get movie by id
|
|
43
|
+
query GetMovieById($id: UUID!) @auth(level: PUBLIC, insecureReason: "Anyone can get a movie by id.") {
|
|
44
|
+
movie(id: $id) {
|
|
45
|
+
id
|
|
46
|
+
title
|
|
47
|
+
imageUrl
|
|
48
|
+
genre
|
|
49
|
+
metadata: movieMetadata_on_movie {
|
|
50
|
+
rating
|
|
51
|
+
releaseYear
|
|
52
|
+
description
|
|
53
|
+
}
|
|
54
|
+
reviews: reviews_on_movie {
|
|
55
|
+
reviewText
|
|
56
|
+
reviewDate
|
|
57
|
+
rating
|
|
58
|
+
user {
|
|
59
|
+
id
|
|
60
|
+
username
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
65
|
|
|
66
|
-
#
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
66
|
+
# Search for movies, actors, and reviews
|
|
67
|
+
query SearchMovie($titleInput: String, $genre: String) @auth(level: PUBLIC, insecureReason: "Anyone can search for movies.") {
|
|
68
|
+
movies(
|
|
69
|
+
where: {
|
|
70
|
+
_and: [{ genre: { eq: $genre } }, { title: { contains: $titleInput } }]
|
|
71
|
+
}
|
|
72
|
+
) {
|
|
73
|
+
id
|
|
74
|
+
title
|
|
75
|
+
genre
|
|
76
|
+
imageUrl
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Example schema for simple movie review app
|
|
2
2
|
|
|
3
|
-
#
|
|
4
|
-
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
|
|
3
|
+
# User table is keyed by Firebase Auth UID.
|
|
4
|
+
type User @table {
|
|
5
|
+
# `@default(expr: "auth.uid")` sets it to Firebase Auth UID during insert and upsert.
|
|
6
|
+
id: String! @default(expr: "auth.uid")
|
|
7
|
+
username: String! @col(dataType: "varchar(50)")
|
|
8
|
+
# The `user: User!` field in the Review table generates the following one-to-many query field.
|
|
9
|
+
# reviews_on_user: [Review!]!
|
|
10
|
+
# The `Review` join table the following many-to-many query field.
|
|
11
|
+
# movies_via_Review: [Movie!]!
|
|
12
|
+
}
|
|
13
13
|
|
|
14
|
-
#
|
|
15
|
-
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
# Movie is keyed by a randomly generated UUID.
|
|
15
|
+
type Movie @table {
|
|
16
|
+
# If you do not pass a 'key' to `@table`, Data Connect automatically adds the following 'id' column.
|
|
17
|
+
# Feel free to uncomment and customize it.
|
|
18
|
+
# id: UUID! @default(expr: "uuidV4()")
|
|
19
|
+
title: String!
|
|
20
|
+
imageUrl: String!
|
|
21
|
+
genre: String
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
# MovieMetadata is a metadata attached to a Movie.
|
|
25
|
+
# Movie <-> MovieMetadata is a one-to-one relationship
|
|
26
|
+
type MovieMetadata @table {
|
|
27
|
+
# @unique ensures each Movie can only one MovieMetadata.
|
|
28
|
+
movie: Movie! @unique
|
|
29
|
+
# The movie field adds the following foreign key field. Feel free to uncomment and customize it.
|
|
30
|
+
# movieId: UUID!
|
|
31
|
+
rating: Float
|
|
32
|
+
releaseYear: Int
|
|
33
|
+
description: String
|
|
34
|
+
}
|
|
35
35
|
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
36
|
+
# Reviews is a join table between User and Movie.
|
|
37
|
+
# It has a composite primary keys `userUid` and `movieId`.
|
|
38
|
+
# A user can leave reviews for many movies. A movie can have reviews from many users.
|
|
39
|
+
# User <-> Review is a one-to-many relationship
|
|
40
|
+
# Movie <-> Review is a one-to-many relationship
|
|
41
|
+
# Movie <-> User is a many-to-many relationship
|
|
42
|
+
type Review @table(name: "Reviews", key: ["movie", "user"]) {
|
|
43
|
+
user: User!
|
|
44
|
+
# The user field adds the following foreign key field. Feel free to uncomment and customize it.
|
|
45
|
+
# userUid: String!
|
|
46
|
+
movie: Movie!
|
|
47
|
+
# The movie field adds the following foreign key field. Feel free to uncomment and customize it.
|
|
48
|
+
# movieId: UUID!
|
|
49
|
+
rating: Int
|
|
50
|
+
reviewText: String
|
|
51
|
+
reviewDate: Date! @default(expr: "request.time")
|
|
52
|
+
}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getFrameworksFromPackageJson = exports.frameworksMap = exports.SUPPORTED_FRAMEWORKS = exports.resolvePackageJson = exports.getPlatformFromFolder = exports.pickService = exports.readGQLFiles = exports.readConnectorYaml = exports.readDataConnectYaml = exports.readFirebaseJson = void 0;
|
|
4
|
-
const fs = require("fs-extra");
|
|
5
|
-
const path = require("path");
|
|
6
|
-
const clc = require("colorette");
|
|
7
|
-
const glob_1 = require("glob");
|
|
8
|
-
const error_1 = require("../error");
|
|
9
|
-
const types_1 = require("./types");
|
|
10
|
-
const utils_1 = require("../utils");
|
|
11
|
-
const load_1 = require("./load");
|
|
12
|
-
function readFirebaseJson(config) {
|
|
13
|
-
if (!(config === null || config === void 0 ? void 0 : config.has("dataconnect"))) {
|
|
14
|
-
return [];
|
|
15
|
-
}
|
|
16
|
-
const validator = (cfg) => {
|
|
17
|
-
if (!cfg["source"]) {
|
|
18
|
-
throw new error_1.FirebaseError("Invalid firebase.json: DataConnect requires `source`");
|
|
19
|
-
}
|
|
20
|
-
return {
|
|
21
|
-
source: cfg["source"],
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
const configs = config.get("dataconnect");
|
|
25
|
-
if (typeof configs === "object" && !Array.isArray(configs)) {
|
|
26
|
-
return [validator(configs)];
|
|
27
|
-
}
|
|
28
|
-
else if (Array.isArray(configs)) {
|
|
29
|
-
return configs.map(validator);
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
throw new error_1.FirebaseError("Invalid firebase.json: dataconnect should be of the form { source: string }");
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
exports.readFirebaseJson = readFirebaseJson;
|
|
36
|
-
async function readDataConnectYaml(sourceDirectory) {
|
|
37
|
-
const file = await (0, utils_1.readFileFromDirectory)(sourceDirectory, "dataconnect.yaml");
|
|
38
|
-
const dataconnectYaml = await (0, utils_1.wrappedSafeLoad)(file.source);
|
|
39
|
-
return validateDataConnectYaml(dataconnectYaml);
|
|
40
|
-
}
|
|
41
|
-
exports.readDataConnectYaml = readDataConnectYaml;
|
|
42
|
-
function validateDataConnectYaml(unvalidated) {
|
|
43
|
-
if (!unvalidated["location"]) {
|
|
44
|
-
throw new error_1.FirebaseError("Missing required field 'location' in dataconnect.yaml");
|
|
45
|
-
}
|
|
46
|
-
return unvalidated;
|
|
47
|
-
}
|
|
48
|
-
async function readConnectorYaml(sourceDirectory) {
|
|
49
|
-
const file = await (0, utils_1.readFileFromDirectory)(sourceDirectory, "connector.yaml");
|
|
50
|
-
const connectorYaml = await (0, utils_1.wrappedSafeLoad)(file.source);
|
|
51
|
-
return validateConnectorYaml(connectorYaml);
|
|
52
|
-
}
|
|
53
|
-
exports.readConnectorYaml = readConnectorYaml;
|
|
54
|
-
function validateConnectorYaml(unvalidated) {
|
|
55
|
-
return unvalidated;
|
|
56
|
-
}
|
|
57
|
-
async function readGQLFiles(sourceDir) {
|
|
58
|
-
if (!fs.existsSync(sourceDir)) {
|
|
59
|
-
return [];
|
|
60
|
-
}
|
|
61
|
-
const files = await (0, glob_1.glob)("**/*.{gql,graphql}", { cwd: sourceDir, absolute: true, nodir: true });
|
|
62
|
-
return files.map((f) => toFile(sourceDir, f));
|
|
63
|
-
}
|
|
64
|
-
exports.readGQLFiles = readGQLFiles;
|
|
65
|
-
function toFile(sourceDir, fullPath) {
|
|
66
|
-
const relPath = path.relative(sourceDir, fullPath);
|
|
67
|
-
if (!fs.existsSync(fullPath)) {
|
|
68
|
-
throw new error_1.FirebaseError(`file ${fullPath} not found`);
|
|
69
|
-
}
|
|
70
|
-
const content = fs.readFileSync(fullPath).toString();
|
|
71
|
-
return {
|
|
72
|
-
path: relPath,
|
|
73
|
-
content,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
async function pickService(projectId, config, serviceId) {
|
|
77
|
-
const serviceCfgs = readFirebaseJson(config);
|
|
78
|
-
let serviceInfo;
|
|
79
|
-
if (serviceCfgs.length === 0) {
|
|
80
|
-
throw new error_1.FirebaseError("No Data Connect services found in firebase.json." +
|
|
81
|
-
`\nYou can run ${clc.bold("firebase init dataconnect")} to add a Data Connect service.`);
|
|
82
|
-
}
|
|
83
|
-
else if (serviceCfgs.length === 1) {
|
|
84
|
-
serviceInfo = await (0, load_1.load)(projectId, config, serviceCfgs[0].source);
|
|
85
|
-
if (serviceId && serviceId !== serviceInfo.dataConnectYaml.serviceId) {
|
|
86
|
-
throw new error_1.FirebaseError(`No service named ${serviceId} declared in firebase.json. Found ${serviceInfo.dataConnectYaml.serviceId}.` +
|
|
87
|
-
`\nYou can run ${clc.bold("firebase init dataconnect")} to add this Data Connect service.`);
|
|
88
|
-
}
|
|
89
|
-
return serviceInfo;
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
if (!serviceId) {
|
|
93
|
-
throw new error_1.FirebaseError("Multiple Data Connect services found in firebase.json. Please specify a service ID to use.");
|
|
94
|
-
}
|
|
95
|
-
const infos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId, config, c.source)));
|
|
96
|
-
const maybe = infos.find((i) => i.dataConnectYaml.serviceId === serviceId);
|
|
97
|
-
if (!maybe) {
|
|
98
|
-
throw new error_1.FirebaseError(`No service named ${serviceId} declared in firebase.json. Found ${infos.map((i) => i.dataConnectYaml.serviceId).join(", ")}.` +
|
|
99
|
-
`\nYou can run ${clc.bold("firebase init dataconnect")} to add this Data Connect service.`);
|
|
100
|
-
}
|
|
101
|
-
return maybe;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
exports.pickService = pickService;
|
|
105
|
-
const WEB_INDICATORS = ["package.json", "package-lock.json", "node_modules"];
|
|
106
|
-
const IOS_INDICATORS = ["info.plist", "podfile", "package.swift", ".xcodeproj"];
|
|
107
|
-
const ANDROID_INDICATORS = ["androidmanifest.xml", "build.gradle", "build.gradle.kts"];
|
|
108
|
-
const DART_INDICATORS = ["pubspec.yaml", "pubspec.lock"];
|
|
109
|
-
const IOS_POSTFIX_INDICATORS = [".xcworkspace", ".xcodeproj"];
|
|
110
|
-
async function getPlatformFromFolder(dirPath) {
|
|
111
|
-
const fileNames = await fs.readdir(dirPath);
|
|
112
|
-
let hasWeb = false;
|
|
113
|
-
let hasAndroid = false;
|
|
114
|
-
let hasIOS = false;
|
|
115
|
-
let hasDart = false;
|
|
116
|
-
for (const fileName of fileNames) {
|
|
117
|
-
const cleanedFileName = fileName.toLowerCase();
|
|
118
|
-
hasWeb || (hasWeb = WEB_INDICATORS.some((indicator) => indicator === cleanedFileName));
|
|
119
|
-
hasAndroid || (hasAndroid = ANDROID_INDICATORS.some((indicator) => indicator === cleanedFileName));
|
|
120
|
-
hasIOS || (hasIOS = IOS_INDICATORS.some((indicator) => indicator === cleanedFileName) ||
|
|
121
|
-
IOS_POSTFIX_INDICATORS.some((indicator) => cleanedFileName.endsWith(indicator)));
|
|
122
|
-
hasDart || (hasDart = DART_INDICATORS.some((indicator) => indicator === cleanedFileName));
|
|
123
|
-
}
|
|
124
|
-
if (!hasWeb && !hasAndroid && !hasIOS && !hasDart) {
|
|
125
|
-
return types_1.Platform.NONE;
|
|
126
|
-
}
|
|
127
|
-
else if (hasWeb && !hasAndroid && !hasIOS && !hasDart) {
|
|
128
|
-
return types_1.Platform.WEB;
|
|
129
|
-
}
|
|
130
|
-
else if (hasAndroid && !hasWeb && !hasIOS && !hasDart) {
|
|
131
|
-
return types_1.Platform.ANDROID;
|
|
132
|
-
}
|
|
133
|
-
else if (hasIOS && !hasWeb && !hasAndroid && !hasDart) {
|
|
134
|
-
return types_1.Platform.IOS;
|
|
135
|
-
}
|
|
136
|
-
else if (hasDart && !hasWeb && !hasIOS && !hasAndroid) {
|
|
137
|
-
return types_1.Platform.FLUTTER;
|
|
138
|
-
}
|
|
139
|
-
return types_1.Platform.MULTIPLE;
|
|
140
|
-
}
|
|
141
|
-
exports.getPlatformFromFolder = getPlatformFromFolder;
|
|
142
|
-
async function resolvePackageJson(packageJsonPath) {
|
|
143
|
-
let validPackageJsonPath = packageJsonPath;
|
|
144
|
-
if (!packageJsonPath.endsWith("package.json")) {
|
|
145
|
-
validPackageJsonPath = path.join(packageJsonPath, "package.json");
|
|
146
|
-
}
|
|
147
|
-
validPackageJsonPath = path.resolve(validPackageJsonPath);
|
|
148
|
-
try {
|
|
149
|
-
return JSON.parse((await fs.readFile(validPackageJsonPath)).toString());
|
|
150
|
-
}
|
|
151
|
-
catch (_a) {
|
|
152
|
-
return undefined;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
exports.resolvePackageJson = resolvePackageJson;
|
|
156
|
-
exports.SUPPORTED_FRAMEWORKS = ["react", "angular"];
|
|
157
|
-
exports.frameworksMap = {
|
|
158
|
-
react: ["react", "next"],
|
|
159
|
-
angular: ["@angular/core"],
|
|
160
|
-
};
|
|
161
|
-
function getFrameworksFromPackageJson(packageJson) {
|
|
162
|
-
var _a, _b;
|
|
163
|
-
const devDependencies = Object.keys((_a = packageJson.devDependencies) !== null && _a !== void 0 ? _a : {});
|
|
164
|
-
const dependencies = Object.keys((_b = packageJson.dependencies) !== null && _b !== void 0 ? _b : {});
|
|
165
|
-
const allDeps = Array.from(new Set([...devDependencies, ...dependencies]));
|
|
166
|
-
return exports.SUPPORTED_FRAMEWORKS.filter((framework) => exports.frameworksMap[framework].find((dep) => allDeps.includes(dep)));
|
|
167
|
-
}
|
|
168
|
-
exports.getFrameworksFromPackageJson = getFrameworksFromPackageJson;
|
|
File without changes
|
|
File without changes
|