@stackable-labs/cli-app-extension 1.35.2 → 1.36.0

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.
Files changed (2) hide show
  1. package/dist/index.js +92 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1053,6 +1053,28 @@ var fetchExtensions = async (token, appId) => {
1053
1053
  ])
1054
1054
  );
1055
1055
  };
1056
+ var fetchProject = async (token, appId, projectId) => {
1057
+ const baseUrl = getAdminApiBaseUrl();
1058
+ const res = await fetch(`${baseUrl}/app-extension/${appId}/projects/${projectId}`, {
1059
+ headers: authHeaders(token)
1060
+ });
1061
+ if (!res.ok) {
1062
+ throw new Error(`Failed to fetch project: ${res.status} ${res.statusText}`);
1063
+ }
1064
+ return res.json();
1065
+ };
1066
+ var updateProject = async (token, appId, projectId, payload) => {
1067
+ const baseUrl = getAdminApiBaseUrl();
1068
+ const res = await fetch(`${baseUrl}/app-extension/${appId}/projects/${projectId}`, {
1069
+ method: "PUT",
1070
+ headers: authHeaders(token),
1071
+ body: JSON.stringify(payload)
1072
+ });
1073
+ if (!res.ok) {
1074
+ const body = await res.text();
1075
+ throw new Error(`Failed to update project: ${res.status} ${body}`);
1076
+ }
1077
+ };
1056
1078
  var requestDevSessionToken = async (token, appId, extensionId) => {
1057
1079
  const baseUrl = getAdminApiBaseUrl();
1058
1080
  const res = await fetch(`${baseUrl}/app-extension/${appId}/dev-session`, {
@@ -1731,6 +1753,17 @@ var scaffold = async (options) => {
1731
1753
  previewPort: options.previewPort,
1732
1754
  manifest: null
1733
1755
  });
1756
+ if (options.projectFiles) {
1757
+ const extensionSrcDir = join2(dir, "packages/extension/src");
1758
+ for (const [filename, content] of Object.entries(options.projectFiles)) {
1759
+ await writeFile2(join2(extensionSrcDir, filename), content);
1760
+ }
1761
+ }
1762
+ if (options.projectManifest) {
1763
+ const manifestPath = join2(dir, "packages/extension/public/manifest.json");
1764
+ await writeFile2(manifestPath, `${JSON.stringify(options.projectManifest, null, 2)}
1765
+ `);
1766
+ }
1734
1767
  return options;
1735
1768
  };
1736
1769
 
@@ -1809,6 +1842,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
1809
1842
  const [confirmedPermissions, setConfirmedPermissions] = useState10([]);
1810
1843
  const [confirmedAllowedDomains, setConfirmedAllowedDomains] = useState10([]);
1811
1844
  const [outputDir, setOutputDir] = useState10("");
1845
+ const [studioProject, setStudioProject] = useState10(null);
1812
1846
  const [progressSteps, setProgressSteps] = useState10(PROGRESS_STEPS[command]);
1813
1847
  const [errorMessage, setErrorMessage] = useState10();
1814
1848
  const updateStep = useCallback((index, status) => {
@@ -1823,9 +1857,17 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
1823
1857
  skipped.add("targets");
1824
1858
  }
1825
1859
  if (options?.extensionPort || options?.previewPort) skipped.add("settings");
1826
- if (command === "update" /* UPDATE */) {
1827
- if (options?.appId) skipped.add("app");
1828
- if (initialExtensionId) skipped.add("extensionSelect");
1860
+ if (options?.appId) skipped.add("app");
1861
+ if (command === "update" /* UPDATE */ && initialExtensionId) skipped.add("extensionSelect");
1862
+ if (studioProject) {
1863
+ if (command === "create" /* CREATE */) {
1864
+ skipped.add("name");
1865
+ skipped.add("template");
1866
+ skipped.add("targets");
1867
+ }
1868
+ if (command === "scaffold" /* SCAFFOLD */ && studioProject.extensionId) {
1869
+ skipped.add("extensionSelect");
1870
+ }
1829
1871
  }
1830
1872
  return base.filter((s) => !skipped.has(s));
1831
1873
  }, [
@@ -1833,6 +1875,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
1833
1875
  initialName,
1834
1876
  initialExtensionId,
1835
1877
  templateFlavor,
1878
+ studioProject,
1836
1879
  options?.template,
1837
1880
  options?.extensionPort,
1838
1881
  options?.previewPort,
@@ -1847,6 +1890,37 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
1847
1890
  }, [activeSteps]);
1848
1891
  const handleAppSelect = async (app) => {
1849
1892
  setSelectedApp(app);
1893
+ if (options?.project && (command === "create" /* CREATE */ || command === "scaffold" /* SCAFFOLD */)) {
1894
+ try {
1895
+ const project = await fetchProject(token, app.id, options.project);
1896
+ setStudioProject(project);
1897
+ setName(project.name);
1898
+ setTargets(project.manifest.targets);
1899
+ if (project.extensionId) {
1900
+ setExtensionId(project.extensionId);
1901
+ }
1902
+ if (command === "create" /* CREATE */) {
1903
+ if (options?.extensionPort || options?.previewPort) {
1904
+ setOutputDir(join3(process.cwd(), toKebabCase(project.name)));
1905
+ setStep("confirm");
1906
+ } else {
1907
+ setStep("settings");
1908
+ }
1909
+ } else if (command === "scaffold" /* SCAFFOLD */) {
1910
+ if (project.extensionId) {
1911
+ setStep("confirmTargets");
1912
+ } else {
1913
+ setStep("extensionSelect");
1914
+ }
1915
+ }
1916
+ return;
1917
+ } catch (err) {
1918
+ const message = err instanceof Error ? err.message : String(err);
1919
+ setErrorMessage(`Failed to fetch Studio project: ${message}`);
1920
+ setStep("error");
1921
+ return;
1922
+ }
1923
+ }
1850
1924
  if (command === "update" /* UPDATE */ && initialExtensionId) {
1851
1925
  try {
1852
1926
  const extensions = await fetchExtensions(token, app.id);
@@ -2069,9 +2143,21 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
2069
2143
  templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0,
2070
2144
  outputDir,
2071
2145
  extensionPort,
2072
- previewPort
2146
+ previewPort,
2147
+ ...studioProject ? {
2148
+ projectFiles: studioProject.files,
2149
+ projectManifest: studioProject.manifest
2150
+ } : {}
2073
2151
  });
2074
2152
  updateStep(scaffoldStepOffset + 0, "done");
2153
+ if (command === "create" /* CREATE */ && studioProject && !studioProject.extensionId) {
2154
+ try {
2155
+ await updateProject(token, selectedApp.id, studioProject.id, {
2156
+ extensionId: resolvedExtensionId
2157
+ });
2158
+ } catch {
2159
+ }
2160
+ }
2075
2161
  if (command === "create" /* CREATE */) {
2076
2162
  const manifestPath = join3(outputDir, "packages/extension/public/manifest.json");
2077
2163
  try {
@@ -3247,7 +3333,7 @@ var ensureToken = async () => {
3247
3333
  }
3248
3334
  };
3249
3335
  program.name("stackable-app-extension").description("Stackable Labs - App Extension developer CLI").version(version);
3250
- program.command("create" /* CREATE */).description("Create a new Extension project").argument("[name]", "Extension project name").option("--template <flavor>", "Template flavor: minimal, starter, kitchen-sink").option("--extension-port <port>", "Extension dev server port (default: 6543)").option("--preview-port <port>", "Preview dev server port").option("--skip-install", "Skip package manager install").option("--skip-git", "Skip git initialization").action(async (name, options) => {
3336
+ program.command("create" /* CREATE */).description("Create a new Extension project").argument("[name]", "Extension project name").option("--app-id <id>", "Skip App selection").option("--project <id>", "Studio project ID (fetches files/manifest from Studio)").option("--template <flavor>", "Template flavor: minimal, starter, kitchen-sink").option("--extension-port <port>", "Extension dev server port (default: 6543)").option("--preview-port <port>", "Preview dev server port").option("--skip-install", "Skip package manager install").option("--skip-git", "Skip git initialization").action(async (name, options) => {
3251
3337
  const auth2 = await ensureToken();
3252
3338
  if (!auth2) {
3253
3339
  return;
@@ -3267,7 +3353,7 @@ program.command("create" /* CREATE */).description("Create a new Extension proje
3267
3353
  )
3268
3354
  );
3269
3355
  });
3270
- program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project from an existing Extension").option("--extension-port <port>", "Extension dev server port (default: 6543)").option("--preview-port <port>", "Preview dev server port").option("--skip-install", "Skip package manager install").option("--skip-git", "Skip git initialization").action(async (options) => {
3356
+ program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project from an existing Extension").option("--app-id <id>", "Skip App selection").option("--project <id>", "Studio project ID (fetches files/manifest from Studio)").option("--extension-port <port>", "Extension dev server port (default: 6543)").option("--preview-port <port>", "Preview dev server port").option("--skip-install", "Skip package manager install").option("--skip-git", "Skip git initialization").action(async (options) => {
3271
3357
  const auth2 = await ensureToken();
3272
3358
  if (!auth2) {
3273
3359
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackable-labs/cli-app-extension",
3
- "version": "1.35.2",
3
+ "version": "1.36.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "bin": {