Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added insomia importer #525

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
.history
.svn/
migrate_working_dir/
.fvm
.fvmrc

# IntelliJ related
*.iml
Expand Down
3 changes: 2 additions & 1 deletion lib/consts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ enum CodegenLanguage {

enum ImportFormat {
curl("cURL"),
postman("Postman Collection v2.1");
postman("Postman Collection v2.1"),
insomnia("Insomnia v4");

const ImportFormat(this.label);
final String label;
Expand Down
24 changes: 21 additions & 3 deletions lib/importer/import_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:apidash/utils/envvar_utils.dart';
import 'package:apidash_design_system/apidash_design_system.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
Expand All @@ -10,9 +11,6 @@ void importToCollectionPane(
WidgetRef ref,
ScaffoldMessengerState sm,
) {
// TODO: The dialog must have a feature to paste contents in a text field
// Also, a mechanism can be added where on importing a file it shows the
// contents in the text field and then the user presses ok to add it to collection
showImportDialog(
context: context,
importFormat: ref.watch(importFormatStateProvider),
Expand All @@ -26,6 +24,26 @@ void importToCollectionPane(
sm.hideCurrentSnackBar();
file.readAsString().then(
(content) {
kEnvImporter
.getInsomniaEnvironment(importFormatType, content)
.then((environment) {
debugPrint('Environment: $environment');
debugPrint('Environment values: ${environment?.resources}');

if (environment != null) {
if (environment.resources == null ||
environment.resources!.isEmpty) {
sm.showSnackBar(getSnackBar("No environment variables imported",
small: false));
} else {
var env = createNewEnvironment(ref, environment);

sm.showSnackBar(getSnackBar(
"Successfully imported ${env.length} environment variables",
small: false));
}
}
});
kImporter
.getHttpRequestModelList(importFormatType, content)
.then((importedRequestModels) {
Expand Down
13 changes: 13 additions & 0 deletions lib/importer/importer.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:apidash/consts.dart';
import 'package:apidash_core/apidash_core.dart';
import 'package:insomnia_collection/models/insomnia_environment.dart';

class Importer {
Future<List<(String?, HttpRequestModel)>?> getHttpRequestModelList(
Expand All @@ -12,8 +13,20 @@ class Importer {
?.map((t) => (null, t))
.toList(),
ImportFormat.postman => PostmanIO().getHttpRequestModelList(content),
ImportFormat.insomnia => InsomniaIO().getHttpRequestModelList(content),
};
}
}

class EnvImporter {
Future<InsomniaEnvironment?> getInsomniaEnvironment(
ImportFormat fileType, String content) async {
return switch (fileType) {
ImportFormat.insomnia => InsomniaIO().getInsomiaEnvironment(content),
_ => null
};
}
}

final kImporter = Importer();
final kEnvImporter = EnvImporter();
1 change: 1 addition & 0 deletions lib/screens/envvar/environments_pane.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class EnvironmentsPane extends ConsumerWidget {
ref
.read(environmentsStateNotifierProvider.notifier)
.addEnvironment();
// createNewEnvironment(ref);
},
),
kVSpacer10,
Expand Down
43 changes: 43 additions & 0 deletions lib/utils/envvar_utils.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,49 @@
import 'package:apidash/providers/environment_providers.dart';
import 'package:apidash_core/apidash_core.dart';
import 'package:apidash/consts.dart';
import 'package:apidash/models/models.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:insomnia_collection/models/insomnia_environment.dart';

List<EnvironmentVariableModel> createNewEnvironment(WidgetRef ref, InsomniaEnvironment environment) {
// Step 1: Add a new environment
ref.read(environmentsStateNotifierProvider.notifier).addEnvironment();

// Step 2: Get the ID of the newly created environment
final newEnvironmentId =
ref.read(selectedEnvironmentIdStateProvider.notifier).state;

debugPrint('New id is $newEnvironmentId');

// Step 3: Update the new environment with a name and variables
if (newEnvironmentId != null) {
if (environment.resources == null || environment.resources!.isEmpty) {
debugPrint('No env variables found');
return [];
}
List<EnvironmentVariableModel> variables = [];
for (var env in environment.resources!) {
variables.add(EnvironmentVariableModel(
key: env.key,
value: env.value,
enabled: env.enabled ?? true,
type: env.type == "secret"
? EnvironmentVariableType.secret
: EnvironmentVariableType.variable,
));
}
ref.read(environmentsStateNotifierProvider.notifier).updateEnvironment(
newEnvironmentId,
name: environment.name ?? "Untitled",
values: variables,
);
return variables;
} else {
debugPrint('No env id found');
return [];
}
}

String getEnvironmentTitle(String? name) {
if (name == null || name.trim() == "") {
Expand Down
1 change: 1 addition & 0 deletions packages/apidash_core/lib/import_export/import_export.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export 'curl_io.dart';
export 'postman_io.dart';
export 'insomnia_io.dart';
122 changes: 122 additions & 0 deletions packages/apidash_core/lib/import_export/insomnia_io.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import 'package:insomnia_collection/models/insomnia_environment.dart';
import 'package:seed/seed.dart';
import '../consts.dart';
import '../models/models.dart';
import '../utils/utils.dart';
import 'package:insomnia_collection/insomnia_collection.dart' as ins;

class InsomniaIO {
List<(String?, HttpRequestModel)>? getHttpRequestModelList(String content) {
content = content.trim();
try {
final ic = ins.insomniaCollectionFromJsonStr(content);
final requests = ins.getRequestsFromInsomniaCollection(ic);

/// TODO; Get env from the insomnia collection
// final environmentVariables = ins.getEnvironmentVariablesFromInsomniaEnvironment(env);

return requests
.map((req) => (req.$1, insomniaRequestToHttpRequestModel(req.$2)))
.toList();
} catch (e) {
return null;
}
}

InsomniaEnvironment? getInsomiaEnvironment(String content) {
content = content.trim();
try {
final env = ins.insomniaEnvironmentFromJsonStr(content);

return env;
} catch (e) {
return null;
}
}

HttpRequestModel insomniaRequestToHttpRequestModel(ins.Resource request) {
HTTPVerb method;

try {
method = HTTPVerb.values.byName((request.method ?? "").toLowerCase());
} catch (e) {
method = kDefaultHttpMethod;
}
String url = stripUrlParams(request.url ?? "");
List<NameValueModel> headers = [];
List<bool> isHeaderEnabledList = [];

List<NameValueModel> params = [];
List<bool> isParamEnabledList = [];

for (var header in request.headers ?? <ins.Header>[]) {
var name = header.name ?? "";
var value = header.value ?? "";
var activeHeader = header.disabled ?? false;
headers.add(NameValueModel(name: name, value: value));
isHeaderEnabledList.add(!activeHeader);
}

for (var query in request.parameters ?? <ins.Parameter>[]) {
var name = query.name ?? "";
var value = query.value;
var activeQuery = query.disabled ?? false;
params.add(NameValueModel(name: name, value: value));
isParamEnabledList.add(!activeQuery);
}

ContentType bodyContentType = kDefaultContentType;
String? body;
List<FormDataModel>? formData;
if (request.body != null) {
if (request.body?.mimeType != null) {
try {
if (request.body?.mimeType == 'text/plain') {
bodyContentType = ContentType.text;
} else if (request.body?.mimeType == 'application/json') {
bodyContentType = ContentType.json;
} else if (request.body?.mimeType == 'multipart/form-data') {
bodyContentType = ContentType.formdata;
formData = [];
for (var fd in request.body?.params ?? <ins.Formdatum>[]) {
var name = fd.name ?? "";
FormDataType formDataType;
try {
formDataType = FormDataType.values.byName(fd.type ?? "");
} catch (e) {
formDataType = FormDataType.text;
}
var value = switch (formDataType) {
FormDataType.text => fd.value ?? "",
FormDataType.file => fd.src ?? ""
};
formData.add(FormDataModel(
name: name,
value: value,
type: formDataType,
));
}
} else {
bodyContentType =
ContentType.values.byName(request.body?.mimeType ?? "");
}
} catch (e) {
bodyContentType = kDefaultContentType;
}
body = request.body?.text;
}
}

return HttpRequestModel(
method: method,
url: url,
headers: headers,
params: params,
isHeaderEnabledList: isHeaderEnabledList,
isParamEnabledList: isParamEnabledList,
body: body,
bodyContentType: bodyContentType,
formData: formData,
);
}
}
2 changes: 2 additions & 0 deletions packages/apidash_core/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ dependencies:
http_parser: ^4.0.2
postman:
path: ../postman
insomnia_collection:
path: ../insomnia_collection
seed: ^0.0.3
xml: ^6.3.0

Expand Down
29 changes: 29 additions & 0 deletions packages/insomnia_collection/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
build/
3 changes: 3 additions & 0 deletions packages/insomnia_collection/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 0.0.1

- Implement fromJson object and fromJson String for Insomnia v4 json format
Loading