@fleetbase/registry-bridge-engine 0.0.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/.php-cs-fixer.php +29 -0
- package/LICENSE.md +651 -0
- package/README.md +122 -0
- package/addon/adapters/registry-bridge.js +5 -0
- package/addon/adapters/registry-extension-bundle.js +1 -0
- package/addon/adapters/registry-extension.js +1 -0
- package/addon/components/extension-card.hbs +12 -0
- package/addon/components/extension-card.js +235 -0
- package/addon/components/extension-form.hbs +237 -0
- package/addon/components/extension-form.js +123 -0
- package/addon/components/extension-modal-title.hbs +14 -0
- package/addon/components/extension-modal-title.js +20 -0
- package/addon/components/extension-monetize-form.hbs +56 -0
- package/addon/components/extension-monetize-form.js +7 -0
- package/addon/components/extension-pending-publish-viewer.hbs +52 -0
- package/addon/components/extension-pending-publish-viewer.js +37 -0
- package/addon/components/extension-reviewer-control.hbs +68 -0
- package/addon/components/extension-reviewer-control.js +68 -0
- package/addon/components/modals/confirm-extension-purchase.hbs +5 -0
- package/addon/components/modals/confirm-extension-purchase.js +3 -0
- package/addon/components/modals/extension-details.hbs +69 -0
- package/addon/components/modals/extension-details.js +33 -0
- package/addon/components/modals/extension-purchase-form.hbs +5 -0
- package/addon/components/modals/extension-purchase-form.js +3 -0
- package/addon/components/modals/extension-uninstall.hbs +25 -0
- package/addon/components/modals/extension-uninstall.js +11 -0
- package/addon/components/modals/select-extension-bundle.hbs +43 -0
- package/addon/components/modals/select-extension-bundle.js +31 -0
- package/addon/components/progress-bar.hbs +12 -0
- package/addon/components/progress-bar.js +8 -0
- package/addon/controllers/application.js +6 -0
- package/addon/controllers/developers/analytics.js +26 -0
- package/addon/controllers/developers/extensions/edit/bundles.js +70 -0
- package/addon/controllers/developers/extensions/edit/index.js +3 -0
- package/addon/controllers/developers/extensions/edit/monetize.js +7 -0
- package/addon/controllers/developers/extensions/edit.js +107 -0
- package/addon/controllers/developers/extensions/index.js +3 -0
- package/addon/controllers/developers/extensions/new.js +32 -0
- package/addon/controllers/developers/payments/index.js +39 -0
- package/addon/controllers/developers/payments/onboard.js +67 -0
- package/addon/controllers/explore/category.js +22 -0
- package/addon/controllers/explore/index.js +15 -0
- package/addon/controllers/installed.js +86 -0
- package/addon/controllers/purchased.js +18 -0
- package/addon/engine.js +44 -0
- package/addon/models/registry-extension-bundle.js +62 -0
- package/addon/models/registry-extension.js +215 -0
- package/addon/routes/application.js +12 -0
- package/addon/routes/developers/analytics.js +10 -0
- package/addon/routes/developers/credentials.js +3 -0
- package/addon/routes/developers/extensions/edit/bundles.js +21 -0
- package/addon/routes/developers/extensions/edit/details.js +3 -0
- package/addon/routes/developers/extensions/edit/index.js +3 -0
- package/addon/routes/developers/extensions/edit/monetize.js +3 -0
- package/addon/routes/developers/extensions/edit.js +18 -0
- package/addon/routes/developers/extensions/index.js +10 -0
- package/addon/routes/developers/extensions/new.js +3 -0
- package/addon/routes/developers/extensions.js +3 -0
- package/addon/routes/developers/payments/index.js +26 -0
- package/addon/routes/developers/payments/onboard.js +21 -0
- package/addon/routes/developers/payments.js +3 -0
- package/addon/routes/developers.js +3 -0
- package/addon/routes/explore/category.js +27 -0
- package/addon/routes/explore/index.js +17 -0
- package/addon/routes/explore.js +3 -0
- package/addon/routes/installed.js +10 -0
- package/addon/routes/purchased.js +10 -0
- package/addon/routes.js +28 -0
- package/addon/serializers/registry-extension-bundle.js +15 -0
- package/addon/serializers/registry-extension.js +21 -0
- package/addon/services/stripe.js +83 -0
- package/addon/styles/registry-bridge-engine.css +142 -0
- package/addon/templates/application.hbs +26 -0
- package/addon/templates/developers/analytics.hbs +83 -0
- package/addon/templates/developers/credentials.hbs +1 -0
- package/addon/templates/developers/extensions/edit/bundles.hbs +71 -0
- package/addon/templates/developers/extensions/edit/details.hbs +16 -0
- package/addon/templates/developers/extensions/edit/index.hbs +1 -0
- package/addon/templates/developers/extensions/edit/monetize.hbs +3 -0
- package/addon/templates/developers/extensions/edit.hbs +48 -0
- package/addon/templates/developers/extensions/index.hbs +27 -0
- package/addon/templates/developers/extensions/new.hbs +39 -0
- package/addon/templates/developers/extensions.hbs +1 -0
- package/addon/templates/developers/payments/index.hbs +33 -0
- package/addon/templates/developers/payments/onboard.hbs +48 -0
- package/addon/templates/developers/payments.hbs +1 -0
- package/addon/templates/developers.hbs +1 -0
- package/addon/templates/explore/category.hbs +12 -0
- package/addon/templates/explore/index.hbs +12 -0
- package/addon/templates/explore.hbs +1 -0
- package/addon/templates/installed.hbs +32 -0
- package/addon/templates/purchased.hbs +34 -0
- package/app/adapters/registry-bridge.js +1 -0
- package/app/adapters/registry-extension-bundle.js +1 -0
- package/app/adapters/registry-extension.js +1 -0
- package/app/components/extension-card.js +1 -0
- package/app/components/extension-form.js +1 -0
- package/app/components/extension-modal-title.js +1 -0
- package/app/components/extension-monetize-form.js +1 -0
- package/app/components/extension-pending-publish-viewer.js +1 -0
- package/app/components/extension-reviewer-control.js +1 -0
- package/app/components/modals/confirm-extension-purchase.js +1 -0
- package/app/components/modals/extension-details.js +1 -0
- package/app/components/modals/extension-purchase-form.js +1 -0
- package/app/components/modals/extension-uninstall.js +1 -0
- package/app/components/modals/select-extension-bundle.js +1 -0
- package/app/components/progress-bar.js +1 -0
- package/app/controllers/application.js +1 -0
- package/app/controllers/developers/analytics.js +1 -0
- package/app/controllers/developers/extensions/edit/bundles.js +1 -0
- package/app/controllers/developers/extensions/edit/index.js +1 -0
- package/app/controllers/developers/extensions/edit/monetize.js +1 -0
- package/app/controllers/developers/extensions/edit.js +1 -0
- package/app/controllers/developers/extensions/index.js +1 -0
- package/app/controllers/developers/extensions/new.js +1 -0
- package/app/controllers/developers/payments/index.js +1 -0
- package/app/controllers/developers/payments/onboard.js +1 -0
- package/app/controllers/explore/category.js +1 -0
- package/app/controllers/explore/index.js +1 -0
- package/app/controllers/installed.js +1 -0
- package/app/controllers/purchased.js +1 -0
- package/app/models/registry-extension-bundle.js +1 -0
- package/app/models/registry-extension.js +1 -0
- package/app/routes/developers/analytics.js +1 -0
- package/app/routes/developers/credentials.js +1 -0
- package/app/routes/developers/extensions/edit/bundles.js +1 -0
- package/app/routes/developers/extensions/edit/details.js +1 -0
- package/app/routes/developers/extensions/edit/index.js +1 -0
- package/app/routes/developers/extensions/edit/monetize.js +1 -0
- package/app/routes/developers/extensions/edit.js +1 -0
- package/app/routes/developers/extensions/index.js +1 -0
- package/app/routes/developers/extensions/new.js +1 -0
- package/app/routes/developers/extensions.js +1 -0
- package/app/routes/developers/payments/index.js +1 -0
- package/app/routes/developers/payments/onboard.js +1 -0
- package/app/routes/developers/payments.js +1 -0
- package/app/routes/developers.js +1 -0
- package/app/routes/explore/category.js +1 -0
- package/app/routes/explore/index.js +1 -0
- package/app/routes/explore.js +1 -0
- package/app/routes/installed.js +1 -0
- package/app/routes/purchased.js +1 -0
- package/app/serializers/registry-extension-bundle.js +1 -0
- package/app/serializers/registry-extension.js +1 -0
- package/app/services/stripe.js +1 -0
- package/app/templates/developers/analytics.js +1 -0
- package/app/templates/developers/credentials.js +1 -0
- package/app/templates/developers/extensions/edit/bundles.js +1 -0
- package/app/templates/developers/extensions/edit/details.js +1 -0
- package/app/templates/developers/extensions/edit/index.js +1 -0
- package/app/templates/developers/extensions/edit/monetize.js +1 -0
- package/app/templates/developers/extensions/edit.js +1 -0
- package/app/templates/developers/extensions/index.js +1 -0
- package/app/templates/developers/extensions/new.js +1 -0
- package/app/templates/developers/extensions.js +1 -0
- package/app/templates/developers/payments/index.js +1 -0
- package/app/templates/developers/payments/onboard.js +1 -0
- package/app/templates/developers/payments.js +1 -0
- package/app/templates/developers.js +1 -0
- package/app/templates/explore/category.js +1 -0
- package/app/templates/explore/index.js +1 -0
- package/app/templates/explore.js +1 -0
- package/app/templates/installed.js +1 -0
- package/app/templates/purchased.js +1 -0
- package/composer.json +95 -0
- package/config/environment.js +28 -0
- package/extension.json +10 -0
- package/index.js +26 -0
- package/package.json +129 -0
- package/phpstan.neon.dist +8 -0
- package/phpunit.xml.dist +16 -0
- package/server/.gitattributes +14 -0
- package/server/config/registry-bridge.php +32 -0
- package/server/migrations/2024_03_19_060627_create_registry_users_table.php +42 -0
- package/server/migrations/2024_03_21_051614_create_registry_extensions_table.php +76 -0
- package/server/migrations/2024_03_25_044537_create_registry_extension_bundles_table.php +54 -0
- package/server/migrations/2024_03_29_072101_registry_extension_installs.php +35 -0
- package/server/migrations/2024_07_16_155000_create_registry_extension_purchases.php +41 -0
- package/server/seeders/ExtensionsCategorySeeder.php +359 -0
- package/server/src/Console/Commands/Initialize.php +35 -0
- package/server/src/Console/Commands/PostInstallExtension.php +84 -0
- package/server/src/Exceptions/InstallFailedException.php +21 -0
- package/server/src/Expansions/CategoryExpansion.php +30 -0
- package/server/src/Http/Controllers/Internal/v1/ExtensionInstallerController.php +153 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryAuthController.php +230 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryController.php +54 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryExtensionBundleController.php +112 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryExtensionController.php +257 -0
- package/server/src/Http/Controllers/Internal/v1/RegistryPaymentsController.php +227 -0
- package/server/src/Http/Controllers/RegistryBridgeController.php +13 -0
- package/server/src/Http/Filter/RegistryExtensionFilter.php +80 -0
- package/server/src/Http/Requests/AddRegistryUserRequest.php +47 -0
- package/server/src/Http/Requests/AuthenticateRegistryUserRequest.php +47 -0
- package/server/src/Http/Requests/CreateRegistryExtensionBundleRequest.php +42 -0
- package/server/src/Http/Requests/CreateRegistryExtensionRequest.php +31 -0
- package/server/src/Http/Requests/InstallExtensionRequest.php +30 -0
- package/server/src/Http/Requests/RegistryAuthRequest.php +46 -0
- package/server/src/Http/Requests/RegistryExtensionActionRequest.php +30 -0
- package/server/src/Http/Resources/RegistryUser.php +40 -0
- package/server/src/Models/RegistryExtension.php +656 -0
- package/server/src/Models/RegistryExtensionBundle.php +1015 -0
- package/server/src/Models/RegistryExtensionInstall.php +76 -0
- package/server/src/Models/RegistryExtensionPurchase.php +87 -0
- package/server/src/Models/RegistryUser.php +140 -0
- package/server/src/Providers/RegistryBridgeServiceProvider.php +117 -0
- package/server/src/Support/Bridge.php +53 -0
- package/server/src/Support/Utils.php +19 -0
- package/server/src/routes.php +58 -0
- package/server/tests/Feature.php +5 -0
- package/translations/en-us.yaml +119 -0
- package/tsconfig.declarations.json +10 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import Model, { attr, belongsTo } from '@ember-data/model';
|
|
2
|
+
import { computed } from '@ember/object';
|
|
3
|
+
import { format as formatDate, formatDistanceToNow, isValid as isValidDate } from 'date-fns';
|
|
4
|
+
|
|
5
|
+
export default class RegistryExtensionBundleModel extends Model {
|
|
6
|
+
/** @ids */
|
|
7
|
+
@attr('string') uuid;
|
|
8
|
+
@attr('string') company_uuid;
|
|
9
|
+
@attr('string') created_by_uuid;
|
|
10
|
+
@attr('string') extension_uuid;
|
|
11
|
+
@attr('string') bundle_uuid;
|
|
12
|
+
@attr('string') bundle_id;
|
|
13
|
+
@attr('string') public_id;
|
|
14
|
+
|
|
15
|
+
/** @relationships */
|
|
16
|
+
@belongsTo('file') bundle;
|
|
17
|
+
|
|
18
|
+
/** @attributes */
|
|
19
|
+
@attr('string') bundle_filename;
|
|
20
|
+
@attr('string') bundle_number;
|
|
21
|
+
@attr('string') version;
|
|
22
|
+
@attr('string') status;
|
|
23
|
+
@attr('object') meta;
|
|
24
|
+
|
|
25
|
+
/** @dates */
|
|
26
|
+
@attr('date') created_at;
|
|
27
|
+
@attr('date') updated_at;
|
|
28
|
+
@attr('date') deleted_at;
|
|
29
|
+
|
|
30
|
+
/** @computed */
|
|
31
|
+
@computed('updated_at') get updatedAgo() {
|
|
32
|
+
if (!isValidDate(this.updated_at)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return formatDistanceToNow(this.updated_at);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@computed('updated_at') get updatedAt() {
|
|
40
|
+
if (!isValidDate(this.updated_at)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return formatDate(this.updated_at, 'PP HH:mm');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@computed('created_at') get createdAgo() {
|
|
48
|
+
if (!isValidDate(this.created_at)) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return formatDistanceToNow(this.created_at);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@computed('created_at') get createdAt() {
|
|
56
|
+
if (!isValidDate(this.created_at)) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return formatDate(this.created_at, 'PP HH:mm');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
|
|
2
|
+
import { action, computed } from '@ember/object';
|
|
3
|
+
import { getOwner } from '@ember/application';
|
|
4
|
+
import { format as formatDate, formatDistanceToNow, isValid as isValidDate } from 'date-fns';
|
|
5
|
+
|
|
6
|
+
export default class RegistryExtensionModel extends Model {
|
|
7
|
+
/** @ids */
|
|
8
|
+
@attr('string') uuid;
|
|
9
|
+
@attr('string') company_uuid;
|
|
10
|
+
@attr('string') created_by_uuid;
|
|
11
|
+
@attr('string') registry_user_uuid;
|
|
12
|
+
@attr('string') current_bundle_uuid;
|
|
13
|
+
@attr('string') next_bundle_uuid;
|
|
14
|
+
@attr('string') category_uuid;
|
|
15
|
+
@attr('string') icon_uuid;
|
|
16
|
+
@attr('string') public_id;
|
|
17
|
+
@attr('string') current_bundle_public_id;
|
|
18
|
+
@attr('string') next_bundle_public_id;
|
|
19
|
+
@attr('string') current_bundle_id;
|
|
20
|
+
@attr('string') next_bundle_id;
|
|
21
|
+
|
|
22
|
+
/** @relationships */
|
|
23
|
+
@belongsTo('company') company;
|
|
24
|
+
@belongsTo('user') created_by;
|
|
25
|
+
@belongsTo('category') category;
|
|
26
|
+
@belongsTo('registry-extension-bundle') current_bundle;
|
|
27
|
+
@belongsTo('registry-extension-bundle') next_bundle;
|
|
28
|
+
@belongsTo('file') icon;
|
|
29
|
+
@hasMany('file') screenshots;
|
|
30
|
+
|
|
31
|
+
/** @attributes */
|
|
32
|
+
@attr('string', { defaultValue: 'https://flb-assets.s3.ap-southeast-1.amazonaws.com/static/default-extension-icon.svg' }) icon_url;
|
|
33
|
+
@attr('string') name;
|
|
34
|
+
@attr('string') subtitle;
|
|
35
|
+
@attr('string') category_name;
|
|
36
|
+
@attr('string') publisher_name;
|
|
37
|
+
@attr('boolean') payment_required;
|
|
38
|
+
@attr('string') price;
|
|
39
|
+
@attr('string') sale_price;
|
|
40
|
+
@attr('boolean') on_sale;
|
|
41
|
+
@attr('boolean') subscription_required;
|
|
42
|
+
@attr('string', { defaultValue: 'flat_rate' }) subscription_model;
|
|
43
|
+
@attr('string', { defaultValue: 'monthly' }) subscription_billing_period;
|
|
44
|
+
@attr('string') subscription_amount;
|
|
45
|
+
@attr('array') subscription_tiers;
|
|
46
|
+
@attr('string', { defaultValue: 'USD' }) currency;
|
|
47
|
+
@attr('string') slug;
|
|
48
|
+
@attr('string', { defaultValue: '1.0.0' }) version;
|
|
49
|
+
@attr('string') fa_icon;
|
|
50
|
+
@attr('string') description;
|
|
51
|
+
@attr('string') current_bundle_filename;
|
|
52
|
+
@attr('string') next_bundle_filename;
|
|
53
|
+
@attr('string') promotional_text;
|
|
54
|
+
@attr('string') website_url;
|
|
55
|
+
@attr('string') repo_url;
|
|
56
|
+
@attr('string') support_url;
|
|
57
|
+
@attr('string') privacy_policy_url;
|
|
58
|
+
@attr('string') tos_url;
|
|
59
|
+
@attr('string') copyright;
|
|
60
|
+
@attr('string') primary_language;
|
|
61
|
+
@attr('array') tags;
|
|
62
|
+
@attr('array') languages;
|
|
63
|
+
@attr('object') meta;
|
|
64
|
+
@attr('boolean') core_service;
|
|
65
|
+
@attr('boolean') is_purchased;
|
|
66
|
+
@attr('boolean') is_installed;
|
|
67
|
+
@attr('string', { defaultValue: 'pending' }) status;
|
|
68
|
+
|
|
69
|
+
/** @dates */
|
|
70
|
+
@attr('date') created_at;
|
|
71
|
+
@attr('date') updated_at;
|
|
72
|
+
@attr('date') deleted_at;
|
|
73
|
+
|
|
74
|
+
/** @computed */
|
|
75
|
+
@computed('updated_at') get updatedAgo() {
|
|
76
|
+
if (!isValidDate(this.updated_at)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return formatDistanceToNow(this.updated_at);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@computed('updated_at') get updatedAt() {
|
|
84
|
+
if (!isValidDate(this.updated_at)) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return formatDate(this.updated_at, 'MMMM, dd yyyy');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@computed('created_at') get createdAgo() {
|
|
92
|
+
if (!isValidDate(this.created_at)) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return formatDistanceToNow(this.created_at);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
@computed('created_at') get createdAt() {
|
|
100
|
+
if (!isValidDate(this.created_at)) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return formatDate(this.created_at, 'MMMM, dd yyyy');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** @methods */
|
|
108
|
+
/**
|
|
109
|
+
* Submits the registry extension for review.
|
|
110
|
+
*
|
|
111
|
+
* @return {Promise<RegistryExtensionModel>}
|
|
112
|
+
* @memberof RegistryExtensionModel
|
|
113
|
+
*/
|
|
114
|
+
@action submitForReview(params = {}) {
|
|
115
|
+
const owner = getOwner(this);
|
|
116
|
+
const fetch = owner.lookup('service:fetch');
|
|
117
|
+
|
|
118
|
+
return fetch.post(`registry-extensions/${this.id}/submit`, params, { namespace: '~registry/v1', normalizeToEmberData: true, modelType: 'registry-extension' });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Submits the registry extension for approval.
|
|
123
|
+
*
|
|
124
|
+
* @return {Promise<RegistryExtensionModel>}
|
|
125
|
+
* @memberof RegistryExtensionModel
|
|
126
|
+
*/
|
|
127
|
+
@action approve(params = {}) {
|
|
128
|
+
const owner = getOwner(this);
|
|
129
|
+
const fetch = owner.lookup('service:fetch');
|
|
130
|
+
|
|
131
|
+
return fetch.post('registry-extensions/approve', { id: this.id, ...params }, { namespace: '~registry/v1', normalizeToEmberData: true, modelType: 'registry-extension' });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Submits the registry extension for rejection.
|
|
136
|
+
*
|
|
137
|
+
* @return {Promise<RegistryExtensionModel>}
|
|
138
|
+
* @memberof RegistryExtensionModel
|
|
139
|
+
*/
|
|
140
|
+
@action reject(params = {}) {
|
|
141
|
+
const owner = getOwner(this);
|
|
142
|
+
const fetch = owner.lookup('service:fetch');
|
|
143
|
+
|
|
144
|
+
return fetch.post('registry-extensions/reject', { id: this.id, ...params }, { namespace: '~registry/v1', normalizeToEmberData: true, modelType: 'registry-extension' });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Downloads the extension latest bundle Zip.
|
|
149
|
+
*
|
|
150
|
+
* @return {Promise<>}
|
|
151
|
+
* @memberof RegistryExtensionModel
|
|
152
|
+
*/
|
|
153
|
+
@action downloadBundle() {
|
|
154
|
+
const owner = getOwner(this);
|
|
155
|
+
const fetch = owner.lookup('service:fetch');
|
|
156
|
+
|
|
157
|
+
return fetch.download('registry-extensions/download-bundle', { id: this.id }, { namespace: '~registry/v1', fileName: this.latest_bundle_filename, mimeType: 'application/x-zip' });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Install the extension.
|
|
162
|
+
*
|
|
163
|
+
* @return {Promise<>}
|
|
164
|
+
* @memberof RegistryExtensionModel
|
|
165
|
+
*/
|
|
166
|
+
@action install() {
|
|
167
|
+
const owner = getOwner(this);
|
|
168
|
+
const fetch = owner.lookup('service:fetch');
|
|
169
|
+
|
|
170
|
+
return fetch.post('installer/install', { extension: this.public_id }, { namespace: '~registry/v1' });
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Uninstall the extension.
|
|
175
|
+
*
|
|
176
|
+
* @return {Promise<>}
|
|
177
|
+
* @memberof RegistryExtensionModel
|
|
178
|
+
*/
|
|
179
|
+
@action uninstall() {
|
|
180
|
+
const owner = getOwner(this);
|
|
181
|
+
const fetch = owner.lookup('service:fetch');
|
|
182
|
+
|
|
183
|
+
return fetch.post('installer/uninstall', { extension: this.public_id }, { namespace: '~registry/v1' });
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Adds a new tag to the tags array.
|
|
188
|
+
*
|
|
189
|
+
* This method takes a tag and adds it to the 'tags' array property
|
|
190
|
+
* of the current instance. The 'pushObject' method is used, which is
|
|
191
|
+
* typically available in Ember.js or similar frameworks that extend
|
|
192
|
+
* JavaScript array functionalities.
|
|
193
|
+
*
|
|
194
|
+
* @param {string} tag - The tag to be added to the tags array.
|
|
195
|
+
*/
|
|
196
|
+
@action addTag(tag) {
|
|
197
|
+
this.tags.push(tag);
|
|
198
|
+
this.tags = [...this.tags];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Removes a tag from the tags array at a specific index.
|
|
203
|
+
*
|
|
204
|
+
* This method takes an index and removes the element at that position
|
|
205
|
+
* from the 'tags' array property of the current instance. The 'removeAt'
|
|
206
|
+
* method is used, which is typically available in Ember.js or similar
|
|
207
|
+
* frameworks that provide extended array functionalities.
|
|
208
|
+
*
|
|
209
|
+
* @param {number} index - The index of the tag to be removed from the tags array.
|
|
210
|
+
*/
|
|
211
|
+
@action removeTag(index) {
|
|
212
|
+
this.tags.removeAt(index);
|
|
213
|
+
this.tags = [...this.tags];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class ApplicationRoute extends Route {
|
|
5
|
+
@service fetch;
|
|
6
|
+
|
|
7
|
+
async setupController(controller) {
|
|
8
|
+
super.setupController(...arguments);
|
|
9
|
+
// controller.categories = await this.store.query('category', { for: 'extension_category', core_category: 1 });
|
|
10
|
+
controller.categories = await this.fetch.get('categories', {}, { namespace: '~registry/v1', normalizeToEmberData: true, modelType: 'category' });
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class DevelopersAnalyticsRoute extends Route {
|
|
5
|
+
@service store;
|
|
6
|
+
|
|
7
|
+
model() {
|
|
8
|
+
return this.store.query('registry-extension', { is_author: 1 });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
|
|
5
|
+
export default class DevelopersExtensionsEditBundlesRoute extends Route {
|
|
6
|
+
@service store;
|
|
7
|
+
@tracked extension;
|
|
8
|
+
|
|
9
|
+
beforeModel() {
|
|
10
|
+
this.extension = this.modelFor('developers.extensions.edit');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
model() {
|
|
14
|
+
return this.store.query('registry-extension-bundle', { extension_uuid: this.extension.id });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
setupController(controller) {
|
|
18
|
+
super.setupController(...arguments);
|
|
19
|
+
controller.extension = this.extension;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class DevelopersExtensionsEditRoute extends Route {
|
|
5
|
+
@service store;
|
|
6
|
+
|
|
7
|
+
model(params) {
|
|
8
|
+
return this.store.queryRecord('registry-extension', { public_id: params.public_id, single: true });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
setupController(controller) {
|
|
12
|
+
super.setupController(...arguments);
|
|
13
|
+
const isReady = controller.validateExtensionForReview();
|
|
14
|
+
if (isReady === true) {
|
|
15
|
+
controller.isReady = isReady;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class DevelopersExtensionsIndexRoute extends Route {
|
|
5
|
+
@service store;
|
|
6
|
+
|
|
7
|
+
model() {
|
|
8
|
+
return this.store.query('registry-extension', { is_author: 1 });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class DevelopersPaymentsIndexRoute extends Route {
|
|
5
|
+
@service fetch;
|
|
6
|
+
|
|
7
|
+
queryParams = {
|
|
8
|
+
page: { refreshModel: true },
|
|
9
|
+
limit: { refreshModel: true },
|
|
10
|
+
sort: { refreshModel: true },
|
|
11
|
+
query: { refreshModel: true },
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
model() {
|
|
15
|
+
return this.fetch.get('payments/author-received', {}, { namespace: '~registry/v1' });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async setupController(controller) {
|
|
19
|
+
try {
|
|
20
|
+
const { hasStripeConnectAccount } = await this.fetch.get('payments/has-stripe-connect-account', {}, { namespace: '~registry/v1' });
|
|
21
|
+
controller.hasStripeConnectAccount = hasStripeConnectAccount;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
controller.hasStripeConnectAccount = false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class DevelopersPaymentsOnboardRoute extends Route {
|
|
5
|
+
@service fetch;
|
|
6
|
+
@service hostRouter;
|
|
7
|
+
@service notifications;
|
|
8
|
+
|
|
9
|
+
async beforeModel() {
|
|
10
|
+
try {
|
|
11
|
+
const { hasStripeConnectAccount } = await this.fetch.get('payments/has-stripe-connect-account', {}, { namespace: '~registry/v1' });
|
|
12
|
+
if (hasStripeConnectAccount) {
|
|
13
|
+
this.notifications.info('Your account is already enabled to accept payments.');
|
|
14
|
+
this.hostRouter.transitionTo('console.extensions.payments');
|
|
15
|
+
}
|
|
16
|
+
} catch (error) {
|
|
17
|
+
this.notifications.serverError(error);
|
|
18
|
+
this.hostRouter.transitionTo('console.extensions.payments');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class ExploreCategoryRoute extends Route {
|
|
5
|
+
@service store;
|
|
6
|
+
|
|
7
|
+
queryParams = {
|
|
8
|
+
query: {
|
|
9
|
+
refreshModel: false,
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
model({ slug }) {
|
|
14
|
+
return this.store.queryRecord('category', { slug, for: 'extension_category', core_category: 1, single: 1 });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async setupController(controller, model) {
|
|
18
|
+
super.setupController(...arguments);
|
|
19
|
+
const params = { explore: 1, category: model.id };
|
|
20
|
+
const query = controller.query;
|
|
21
|
+
if (query) {
|
|
22
|
+
params.query = controller.query;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
controller.extensions = await this.store.query('registry-extension', params);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class ExploreIndexRoute extends Route {
|
|
5
|
+
@service store;
|
|
6
|
+
|
|
7
|
+
queryParams = {
|
|
8
|
+
query: {
|
|
9
|
+
refreshModel: true,
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
model(params) {
|
|
14
|
+
const { query } = params;
|
|
15
|
+
return this.store.query('registry-extension', { explore: 1, query });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class InstalledRoute extends Route {
|
|
5
|
+
@service fetch;
|
|
6
|
+
|
|
7
|
+
model(params = {}) {
|
|
8
|
+
return this.fetch.get('registry-extensions/installed', params, { namespace: '~registry/v1', normalizeToEmberData: true, modelType: 'registry-extension' });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Route from '@ember/routing/route';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
|
|
4
|
+
export default class PurchasedRoute extends Route {
|
|
5
|
+
@service fetch;
|
|
6
|
+
|
|
7
|
+
model(params = {}) {
|
|
8
|
+
return this.fetch.get('registry-extensions/purchased', params, { namespace: '~registry/v1', normalizeToEmberData: true, modelType: 'registry-extension' });
|
|
9
|
+
}
|
|
10
|
+
}
|
package/addon/routes.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import buildRoutes from 'ember-engines/routes';
|
|
2
|
+
|
|
3
|
+
export default buildRoutes(function () {
|
|
4
|
+
this.route('installed');
|
|
5
|
+
this.route('purchased');
|
|
6
|
+
this.route('developers', function () {
|
|
7
|
+
this.route('extensions', function () {
|
|
8
|
+
this.route('index', { path: '/' });
|
|
9
|
+
this.route('new');
|
|
10
|
+
this.route('edit', { path: '/distribution/:public_id' }, function () {
|
|
11
|
+
this.route('index', { path: '/' });
|
|
12
|
+
this.route('details');
|
|
13
|
+
this.route('bundles');
|
|
14
|
+
this.route('monetize');
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
this.route('analytics');
|
|
18
|
+
this.route('payments', function () {
|
|
19
|
+
this.route('index', { path: '/' });
|
|
20
|
+
this.route('onboard');
|
|
21
|
+
});
|
|
22
|
+
this.route('credentials');
|
|
23
|
+
});
|
|
24
|
+
this.route('explore', { path: '/' }, function () {
|
|
25
|
+
this.route('index', { path: '/' });
|
|
26
|
+
this.route('category', { path: '/:slug' });
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
|
|
2
|
+
import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
|
|
3
|
+
|
|
4
|
+
export default class RegistryExtensionBundleSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
|
|
5
|
+
/**
|
|
6
|
+
* Embedded relationship attributes
|
|
7
|
+
*
|
|
8
|
+
* @var {Object}
|
|
9
|
+
*/
|
|
10
|
+
get attrs() {
|
|
11
|
+
return {
|
|
12
|
+
bundle: { embedded: 'always' },
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
|
|
2
|
+
import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
|
|
3
|
+
|
|
4
|
+
export default class RegistryExtensionSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
|
|
5
|
+
/**
|
|
6
|
+
* Embedded relationship attributes
|
|
7
|
+
*
|
|
8
|
+
* @var {Object}
|
|
9
|
+
*/
|
|
10
|
+
get attrs() {
|
|
11
|
+
return {
|
|
12
|
+
company: { embedded: 'always' },
|
|
13
|
+
created_by: { embedded: 'always' },
|
|
14
|
+
category: { embedded: 'always' },
|
|
15
|
+
icon: { embedded: 'always' },
|
|
16
|
+
current_bundle: { embedded: 'always' },
|
|
17
|
+
next_bundle: { embedded: 'always' },
|
|
18
|
+
screenshots: { embedded: 'always' },
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import Service from '@ember/service';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { later } from '@ember/runloop';
|
|
4
|
+
import config from '../config/environment';
|
|
5
|
+
|
|
6
|
+
const STRIPE_JS_INITIALIZE_DELAY_MS = 900;
|
|
7
|
+
export default class StripeService extends Service {
|
|
8
|
+
@tracked stripe;
|
|
9
|
+
@tracked loaded = false;
|
|
10
|
+
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.loadAndInitialize();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async initEmbeddedCheckout() {
|
|
17
|
+
if (!this.stripe) {
|
|
18
|
+
await this.loadAndInitialize();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (typeof this.stripe.initEmbeddedCheckout === 'function') {
|
|
22
|
+
return this.stripe.initEmbeddedCheckout(...arguments);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
throw new Error('Stripe not initialized!');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getInstance() {
|
|
29
|
+
return this.stripe;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
createStripeInstance(options = {}) {
|
|
33
|
+
this.stripe = Stripe(config.stripe.publishableKey, options);
|
|
34
|
+
return this.stripe;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async loadAndInitialize() {
|
|
38
|
+
return new Promise((resolve) => {
|
|
39
|
+
this.load(() => {
|
|
40
|
+
resolve(this.createStripeInstance());
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
load(callback = null) {
|
|
46
|
+
const stripeJs = document.querySelector('script[data-stripe-js="loaded"]');
|
|
47
|
+
if (stripeJs) {
|
|
48
|
+
later(
|
|
49
|
+
this,
|
|
50
|
+
() => {
|
|
51
|
+
if (typeof callback === 'function') {
|
|
52
|
+
callback();
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
STRIPE_JS_INITIALIZE_DELAY_MS
|
|
56
|
+
);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Create a new script element
|
|
61
|
+
const script = document.createElement('script');
|
|
62
|
+
script.src = 'https://js.stripe.com/v3/';
|
|
63
|
+
script.async = true;
|
|
64
|
+
|
|
65
|
+
// Use a data attribute to mark that the script is loaded
|
|
66
|
+
script.setAttribute('data-stripe-js', 'loaded');
|
|
67
|
+
script.onload = () => {
|
|
68
|
+
this.loaded = true;
|
|
69
|
+
later(
|
|
70
|
+
this,
|
|
71
|
+
() => {
|
|
72
|
+
if (typeof callback === 'function') {
|
|
73
|
+
callback();
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
STRIPE_JS_INITIALIZE_DELAY_MS
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// Append the script to the document's head
|
|
81
|
+
document.head.appendChild(script);
|
|
82
|
+
}
|
|
83
|
+
}
|