+ Generate a Fleetbase registry credentials token.
+
+
+
+
Install fleetbase-cli
+ npm i -g @fleetbase/cli
+
+
+
+
Run
+ flb set-auth {YOUR_TOKEN}
+
+
+
+
+ Run install
+ flb install fleetbase/{{@options.extension.slug}}
+ or
+ flb install {{@options.extension.public_id}}
+
+
+
+
+
\ No newline at end of file
diff --git a/addon/styles/registry-bridge-engine.css b/addon/styles/registry-bridge-engine.css
index 72e8c18..dcfb0f5 100644
--- a/addon/styles/registry-bridge-engine.css
+++ b/addon/styles/registry-bridge-engine.css
@@ -140,3 +140,31 @@ body[data-theme='dark'] .extension-card-container > .extension-card-body-contain
margin-left: 2rem;
margin-bottom: 2rem;
}
+
+.self-managed-install-instructions {
+ list-style: decimal;
+ color: #000;
+ padding-left: 30px;
+ font-size: 1rem;
+}
+
+.self-managed-install-instructions > li {
+ padding-bottom: 0.5rem;
+}
+
+body[data-theme='dark'] .self-managed-install-instructions {
+ list-style: decimal;
+ color: #fff;
+ padding-left: 30px;
+}
+
+.self-managed-install-instructions code {
+ font-family: monospace;
+ padding: 0.05rem 0.2rem;
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
+ background-color: #030712;
+ border: 1px #1f2937 solid;
+ color: #22c55e;
+ border-radius: 0.25rem;
+ font-size: 0.75rem;
+}
diff --git a/app/components/modals/self-managed-install-instructions.js b/app/components/modals/self-managed-install-instructions.js
new file mode 100644
index 0000000..3ec45df
--- /dev/null
+++ b/app/components/modals/self-managed-install-instructions.js
@@ -0,0 +1 @@
+export { default } from '@fleetbase/registry-bridge-engine/components/modals/self-managed-install-instructions';
diff --git a/server/src/Http/Controllers/Internal/v1/RegistryController.php b/server/src/Http/Controllers/Internal/v1/RegistryController.php
index 124f2e6..4b563cf 100644
--- a/server/src/Http/Controllers/Internal/v1/RegistryController.php
+++ b/server/src/Http/Controllers/Internal/v1/RegistryController.php
@@ -6,6 +6,7 @@
use Fleetbase\Http\Resources\Category as CategoryResource;
use Fleetbase\Models\Category;
use Fleetbase\RegistryBridge\Models\RegistryExtension;
+use Illuminate\Http\Request;
class RegistryController extends Controller
{
@@ -51,4 +52,49 @@ public function getInstalledEngines()
return response()->json($installedExtensions);
}
+
+ /**
+ * Lookup and retrieve package information based on the provided package name.
+ *
+ * This method handles a request to lookup a package by its name. It utilizes the `RegistryExtension::lookup` method to find the
+ * corresponding registry extension. If no extension is found or if the extension does not have valid package or composer data,
+ * an error response is returned.
+ *
+ * If a valid extension and its associated bundle are found, the function extracts the package and composer names from the
+ * `package.json` and `composer.json` metadata. These names are then returned in a JSON response.
+ *
+ * @param Request $request the incoming HTTP request containing the 'package' input parameter
+ *
+ * @return \Illuminate\Http\JsonResponse a JSON response containing the package and composer names if found, or an error message otherwise
+ */
+ public function lookupPackage(Request $request)
+ {
+ $packageName = $request->input('package');
+ $registryExtension = RegistryExtension::lookup($packageName);
+ if (!$registryExtension) {
+ return response()->error('No extension found by this name for install');
+ }
+
+ if (!$registryExtension->currentBundle) {
+ return response()->error('No valid package data found for this extension install');
+ }
+
+ $packageJson = $registryExtension->currentBundle->meta['package.json'];
+ if (!$packageJson) {
+ return response()->error('No valid package data found for this extension install');
+ }
+
+ $composerJson = $registryExtension->currentBundle->meta['composer.json'];
+ if (!$composerJson) {
+ return response()->error('No valid package data found for this extension install');
+ }
+
+ $packageJsonName = data_get($packageJson, 'name');
+ $composerJsonName = data_get($composerJson, 'name');
+
+ return response()->json([
+ 'npm' => $packageJsonName,
+ 'composer' => $composerJsonName,
+ ]);
+ }
}
diff --git a/server/src/Models/RegistryExtension.php b/server/src/Models/RegistryExtension.php
index c9bb933..604d1ff 100644
--- a/server/src/Models/RegistryExtension.php
+++ b/server/src/Models/RegistryExtension.php
@@ -15,6 +15,7 @@
use Fleetbase\Traits\HasPublicId;
use Fleetbase\Traits\HasUuid;
use Fleetbase\Traits\Searchable;
+use Illuminate\Support\Str;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
@@ -444,6 +445,39 @@ public static function findByPackageName(string $packageName): ?RegistryExtensio
})->first();
}
+ /**
+ * Lookup a registry extension based on the given package name.
+ *
+ * This method attempts to find a `RegistryExtension` that matches the provided package name. It checks multiple fields including
+ * `uuid`, `public_id`, and `slug`. If the package name starts with 'fleetbase/', it also attempts to match the slug extracted from the package name.
+ *
+ * Additionally, the method checks for the existence of a related `currentBundle` where the `package.json` or `composer.json` metadata
+ * matches the provided package name.
+ *
+ * @param string $packageName the name, UUID, public ID, or slug of the package to lookup
+ *
+ * @return RegistryExtension|null returns the found `RegistryExtension` instance or `null` if no match is found
+ */
+ public static function lookup(string $packageName): ?RegistryExtension
+ {
+ return static::where('status', 'published')->where(function ($query) use ($packageName) {
+ $query->where('uuid', $packageName)
+ ->orWhere('public_id', $packageName)
+ ->orWhere('slug', $packageName);
+
+ // Check for fleetbase/ prefix and match slug
+ if (Str::startsWith($packageName, 'fleetbase/')) {
+ $packageSlug = explode('/', $packageName)[1] ?? null;
+ if ($packageSlug) {
+ $query->orWhere('slug', $packageSlug);
+ }
+ }
+ })->orWhereHas('currentBundle', function ($query) use ($packageName) {
+ $query->where('meta->package.json->name', $packageName)
+ ->orWhere('meta->composer.json->name', $packageName);
+ })->with(['currentBundle'])->first();
+ }
+
/**
* Determines if the current extension instance is ready for submission.
*
diff --git a/server/src/routes.php b/server/src/routes.php
index b475c5a..034becc 100644
--- a/server/src/routes.php
+++ b/server/src/routes.php
@@ -12,7 +12,8 @@
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
-
+// Lookup package endpoint
+Route::get(config('internals.api.routing.prefix', '~registry') . '/v1/lookup', 'Fleetbase\RegistryBridge\Http\Controllers\Internal\v1\RegistryController@lookupPackage');
Route::prefix(config('internals.api.routing.prefix', '~registry'))->middleware(['fleetbase.registry'])->namespace('Fleetbase\RegistryBridge\Http\Controllers')->group(
function ($router) {
/*
diff --git a/tests/integration/components/modals/self-managed-install-instructions-test.js b/tests/integration/components/modals/self-managed-install-instructions-test.js
new file mode 100644
index 0000000..67288ca
--- /dev/null
+++ b/tests/integration/components/modals/self-managed-install-instructions-test.js
@@ -0,0 +1,26 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'dummy/tests/helpers';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | modals/self-managed-install-instructions', function (hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.set('myAction', function(val) { ... });
+
+ await render(hbs``);
+
+ assert.dom().hasText('');
+
+ // Template block usage:
+ await render(hbs`
+
+ template block text
+
+ `);
+
+ assert.dom().hasText('template block text');
+ });
+});