@launch77/cli 1.2.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.
- package/.eslintrc.json +6 -0
- package/dist/app-templates/webapp/.env.ci +6 -0
- package/dist/app-templates/webapp/.env.example +9 -0
- package/dist/app-templates/webapp/.eslintrc.json +6 -0
- package/dist/app-templates/webapp/README.md.hbs +80 -0
- package/dist/app-templates/webapp/app/about/page.tsx.hbs +41 -0
- package/dist/app-templates/webapp/app/dashboard/page.tsx.hbs +51 -0
- package/dist/app-templates/webapp/app/globals.css +31 -0
- package/dist/app-templates/webapp/app/layout.tsx.hbs +26 -0
- package/dist/app-templates/webapp/app/page.tsx.hbs +30 -0
- package/dist/app-templates/webapp/next.config.js +99 -0
- package/dist/app-templates/webapp/package.json.hbs +30 -0
- package/dist/app-templates/webapp/postcss.config.js +6 -0
- package/dist/app-templates/webapp/tailwind.config.ts +24 -0
- package/dist/app-templates/webapp/tsconfig.json +29 -0
- package/dist/app-templates/webapp/vercel.json.hbs +7 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +29 -0
- package/dist/cli.js.map +1 -0
- package/dist/infrastructure/filesystem.d.ts +41 -0
- package/dist/infrastructure/filesystem.d.ts.map +1 -0
- package/dist/infrastructure/filesystem.js +61 -0
- package/dist/infrastructure/filesystem.js.map +1 -0
- package/dist/infrastructure/npm.d.ts +9 -0
- package/dist/infrastructure/npm.d.ts.map +1 -0
- package/dist/infrastructure/npm.js +17 -0
- package/dist/infrastructure/npm.js.map +1 -0
- package/dist/infrastructure/template-engine.d.ts +12 -0
- package/dist/infrastructure/template-engine.d.ts.map +1 -0
- package/dist/infrastructure/template-engine.js +40 -0
- package/dist/infrastructure/template-engine.js.map +1 -0
- package/dist/infrastructure/template-generator.d.ts +9 -0
- package/dist/infrastructure/template-generator.d.ts.map +1 -0
- package/dist/infrastructure/template-generator.js +19 -0
- package/dist/infrastructure/template-generator.js.map +1 -0
- package/dist/infrastructure/template.d.ts +20 -0
- package/dist/infrastructure/template.d.ts.map +1 -0
- package/dist/infrastructure/template.js +53 -0
- package/dist/infrastructure/template.js.map +1 -0
- package/dist/modules/app/commands/create-app.d.ts +3 -0
- package/dist/modules/app/commands/create-app.d.ts.map +1 -0
- package/dist/modules/app/commands/create-app.js +51 -0
- package/dist/modules/app/commands/create-app.js.map +1 -0
- package/dist/modules/app/commands/delete-app.d.ts +3 -0
- package/dist/modules/app/commands/delete-app.d.ts.map +1 -0
- package/dist/modules/app/commands/delete-app.js +109 -0
- package/dist/modules/app/commands/delete-app.js.map +1 -0
- package/dist/modules/app/commands/generate-manifest.d.ts +3 -0
- package/dist/modules/app/commands/generate-manifest.d.ts.map +1 -0
- package/dist/modules/app/commands/generate-manifest.js +62 -0
- package/dist/modules/app/commands/generate-manifest.js.map +1 -0
- package/dist/modules/app/commands/validate-manifest.d.ts +3 -0
- package/dist/modules/app/commands/validate-manifest.d.ts.map +1 -0
- package/dist/modules/app/commands/validate-manifest.js +68 -0
- package/dist/modules/app/commands/validate-manifest.js.map +1 -0
- package/dist/modules/app/errors/app-errors.d.ts +19 -0
- package/dist/modules/app/errors/app-errors.d.ts.map +1 -0
- package/dist/modules/app/errors/app-errors.js +37 -0
- package/dist/modules/app/errors/app-errors.js.map +1 -0
- package/dist/modules/app/index.d.ts +10 -0
- package/dist/modules/app/index.d.ts.map +1 -0
- package/dist/modules/app/index.js +11 -0
- package/dist/modules/app/index.js.map +1 -0
- package/dist/modules/app/lib/manifest-schema.d.ts +39 -0
- package/dist/modules/app/lib/manifest-schema.d.ts.map +1 -0
- package/dist/modules/app/lib/manifest-schema.js +44 -0
- package/dist/modules/app/lib/manifest-schema.js.map +1 -0
- package/dist/modules/app/services/app-svc.d.ts +15 -0
- package/dist/modules/app/services/app-svc.d.ts.map +1 -0
- package/dist/modules/app/services/app-svc.js +90 -0
- package/dist/modules/app/services/app-svc.js.map +1 -0
- package/dist/modules/app/services/manifest-svc.d.ts +28 -0
- package/dist/modules/app/services/manifest-svc.d.ts.map +1 -0
- package/dist/modules/app/services/manifest-svc.js +119 -0
- package/dist/modules/app/services/manifest-svc.js.map +1 -0
- package/dist/modules/app/types/app-types.d.ts +21 -0
- package/dist/modules/app/types/app-types.d.ts.map +1 -0
- package/dist/modules/app/types/app-types.js +5 -0
- package/dist/modules/app/types/app-types.js.map +1 -0
- package/dist/modules/catalog/commands/generate.d.ts +9 -0
- package/dist/modules/catalog/commands/generate.d.ts.map +1 -0
- package/dist/modules/catalog/commands/generate.js +94 -0
- package/dist/modules/catalog/commands/generate.js.map +1 -0
- package/dist/modules/catalog/commands/scan.d.ts +9 -0
- package/dist/modules/catalog/commands/scan.d.ts.map +1 -0
- package/dist/modules/catalog/commands/scan.js +43 -0
- package/dist/modules/catalog/commands/scan.js.map +1 -0
- package/dist/modules/catalog/config/catalog-config.d.ts +49 -0
- package/dist/modules/catalog/config/catalog-config.d.ts.map +1 -0
- package/dist/modules/catalog/config/catalog-config.js +116 -0
- package/dist/modules/catalog/config/catalog-config.js.map +1 -0
- package/dist/modules/catalog/config/catalog-config.test.d.ts +2 -0
- package/dist/modules/catalog/config/catalog-config.test.d.ts.map +1 -0
- package/dist/modules/catalog/config/catalog-config.test.js +362 -0
- package/dist/modules/catalog/config/catalog-config.test.js.map +1 -0
- package/dist/modules/catalog/index.d.ts +9 -0
- package/dist/modules/catalog/index.d.ts.map +1 -0
- package/dist/modules/catalog/index.js +9 -0
- package/dist/modules/catalog/index.js.map +1 -0
- package/dist/modules/catalog/parsers/typescript-parser.d.ts +15 -0
- package/dist/modules/catalog/parsers/typescript-parser.d.ts.map +1 -0
- package/dist/modules/catalog/parsers/typescript-parser.js +82 -0
- package/dist/modules/catalog/parsers/typescript-parser.js.map +1 -0
- package/dist/modules/catalog/scanners/metadata-extractor.d.ts +10 -0
- package/dist/modules/catalog/scanners/metadata-extractor.d.ts.map +1 -0
- package/dist/modules/catalog/scanners/metadata-extractor.js +122 -0
- package/dist/modules/catalog/scanners/metadata-extractor.js.map +1 -0
- package/dist/modules/catalog/scanners/metadata-validator.d.ts +6 -0
- package/dist/modules/catalog/scanners/metadata-validator.d.ts.map +1 -0
- package/dist/modules/catalog/scanners/metadata-validator.js +57 -0
- package/dist/modules/catalog/scanners/metadata-validator.js.map +1 -0
- package/dist/modules/catalog/scanners/ui-component-scanner.d.ts +11 -0
- package/dist/modules/catalog/scanners/ui-component-scanner.d.ts.map +1 -0
- package/dist/modules/catalog/scanners/ui-component-scanner.js +147 -0
- package/dist/modules/catalog/scanners/ui-component-scanner.js.map +1 -0
- package/dist/modules/catalog/schemas/catalog-ui-components.schema.json +161 -0
- package/dist/modules/catalog/schemas/schemas/catalog-ui-components.schema.json +145 -0
- package/dist/modules/catalog/services/catalog-generator-svc.d.ts +27 -0
- package/dist/modules/catalog/services/catalog-generator-svc.d.ts.map +1 -0
- package/dist/modules/catalog/services/catalog-generator-svc.js +100 -0
- package/dist/modules/catalog/services/catalog-generator-svc.js.map +1 -0
- package/dist/modules/catalog/services/catalog-generator-svc.test.d.ts +2 -0
- package/dist/modules/catalog/services/catalog-generator-svc.test.d.ts.map +1 -0
- package/dist/modules/catalog/services/catalog-generator-svc.test.js +201 -0
- package/dist/modules/catalog/services/catalog-generator-svc.test.js.map +1 -0
- package/dist/modules/catalog/services/catalog-svc.d.ts +39 -0
- package/dist/modules/catalog/services/catalog-svc.d.ts.map +1 -0
- package/dist/modules/catalog/services/catalog-svc.js +163 -0
- package/dist/modules/catalog/services/catalog-svc.js.map +1 -0
- package/dist/modules/catalog/types/catalog-types.d.ts +120 -0
- package/dist/modules/catalog/types/catalog-types.d.ts.map +1 -0
- package/dist/modules/catalog/types/catalog-types.js +5 -0
- package/dist/modules/catalog/types/catalog-types.js.map +1 -0
- package/dist/modules/catalog/utils/examples-generator.d.ts +6 -0
- package/dist/modules/catalog/utils/examples-generator.d.ts.map +1 -0
- package/dist/modules/catalog/utils/examples-generator.js +55 -0
- package/dist/modules/catalog/utils/examples-generator.js.map +1 -0
- package/dist/modules/catalog/utils/quality-reporter.d.ts +13 -0
- package/dist/modules/catalog/utils/quality-reporter.d.ts.map +1 -0
- package/dist/modules/catalog/utils/quality-reporter.js +64 -0
- package/dist/modules/catalog/utils/quality-reporter.js.map +1 -0
- package/dist/modules/catalog/validators/component-name-validator.d.ts +20 -0
- package/dist/modules/catalog/validators/component-name-validator.d.ts.map +1 -0
- package/dist/modules/catalog/validators/component-name-validator.js +33 -0
- package/dist/modules/catalog/validators/component-name-validator.js.map +1 -0
- package/dist/modules/catalog/validators/component-name-validator.test.d.ts +2 -0
- package/dist/modules/catalog/validators/component-name-validator.test.d.ts.map +1 -0
- package/dist/modules/catalog/validators/component-name-validator.test.js +196 -0
- package/dist/modules/catalog/validators/component-name-validator.test.js.map +1 -0
- package/dist/modules/deploy/commands/deploy-init-action.d.ts +12 -0
- package/dist/modules/deploy/commands/deploy-init-action.d.ts.map +1 -0
- package/dist/modules/deploy/commands/deploy-init-action.js +220 -0
- package/dist/modules/deploy/commands/deploy-init-action.js.map +1 -0
- package/dist/modules/deploy/commands/deploy-init.d.ts +6 -0
- package/dist/modules/deploy/commands/deploy-init.d.ts.map +1 -0
- package/dist/modules/deploy/commands/deploy-init.js +16 -0
- package/dist/modules/deploy/commands/deploy-init.js.map +1 -0
- package/dist/modules/deploy/commands/deploy-logs-action.d.ts +12 -0
- package/dist/modules/deploy/commands/deploy-logs-action.d.ts.map +1 -0
- package/dist/modules/deploy/commands/deploy-logs-action.js +113 -0
- package/dist/modules/deploy/commands/deploy-logs-action.js.map +1 -0
- package/dist/modules/deploy/commands/deploy-logs.d.ts +6 -0
- package/dist/modules/deploy/commands/deploy-logs.d.ts.map +1 -0
- package/dist/modules/deploy/commands/deploy-logs.js +17 -0
- package/dist/modules/deploy/commands/deploy-logs.js.map +1 -0
- package/dist/modules/deploy/commands/deploy-status-action.d.ts +8 -0
- package/dist/modules/deploy/commands/deploy-status-action.d.ts.map +1 -0
- package/dist/modules/deploy/commands/deploy-status-action.js +153 -0
- package/dist/modules/deploy/commands/deploy-status-action.js.map +1 -0
- package/dist/modules/deploy/commands/deploy-status.d.ts +6 -0
- package/dist/modules/deploy/commands/deploy-status.d.ts.map +1 -0
- package/dist/modules/deploy/commands/deploy-status.js +13 -0
- package/dist/modules/deploy/commands/deploy-status.js.map +1 -0
- package/dist/modules/deploy/index.d.ts +7 -0
- package/dist/modules/deploy/index.d.ts.map +1 -0
- package/dist/modules/deploy/index.js +7 -0
- package/dist/modules/deploy/index.js.map +1 -0
- package/dist/modules/deploy/services/deploy-svc.d.ts +17 -0
- package/dist/modules/deploy/services/deploy-svc.d.ts.map +1 -0
- package/dist/modules/deploy/services/deploy-svc.js +25 -0
- package/dist/modules/deploy/services/deploy-svc.js.map +1 -0
- package/dist/modules/deploy/utils/vercel-extended.d.ts +63 -0
- package/dist/modules/deploy/utils/vercel-extended.d.ts.map +1 -0
- package/dist/modules/deploy/utils/vercel-extended.js +238 -0
- package/dist/modules/deploy/utils/vercel-extended.js.map +1 -0
- package/dist/modules/plugin/commands/plugin-install.d.ts +3 -0
- package/dist/modules/plugin/commands/plugin-install.d.ts.map +1 -0
- package/dist/modules/plugin/commands/plugin-install.js +45 -0
- package/dist/modules/plugin/commands/plugin-install.js.map +1 -0
- package/dist/modules/plugin/errors/plugin-errors.d.ts +16 -0
- package/dist/modules/plugin/errors/plugin-errors.d.ts.map +1 -0
- package/dist/modules/plugin/errors/plugin-errors.js +39 -0
- package/dist/modules/plugin/errors/plugin-errors.js.map +1 -0
- package/dist/modules/plugin/index.d.ts +6 -0
- package/dist/modules/plugin/index.d.ts.map +1 -0
- package/dist/modules/plugin/index.js +9 -0
- package/dist/modules/plugin/index.js.map +1 -0
- package/dist/modules/plugin/lib/plugin-registry.d.ts +15 -0
- package/dist/modules/plugin/lib/plugin-registry.d.ts.map +1 -0
- package/dist/modules/plugin/lib/plugin-registry.js +47 -0
- package/dist/modules/plugin/lib/plugin-registry.js.map +1 -0
- package/dist/modules/plugin/services/plugin-svc.d.ts +10 -0
- package/dist/modules/plugin/services/plugin-svc.d.ts.map +1 -0
- package/dist/modules/plugin/services/plugin-svc.js +44 -0
- package/dist/modules/plugin/services/plugin-svc.js.map +1 -0
- package/dist/modules/plugin/types/plugin-types.d.ts +19 -0
- package/dist/modules/plugin/types/plugin-types.d.ts.map +1 -0
- package/dist/modules/plugin/types/plugin-types.js +2 -0
- package/dist/modules/plugin/types/plugin-types.js.map +1 -0
- package/dist/modules/startup/commands/create-startup.d.ts +3 -0
- package/dist/modules/startup/commands/create-startup.d.ts.map +1 -0
- package/dist/modules/startup/commands/create-startup.js +43 -0
- package/dist/modules/startup/commands/create-startup.js.map +1 -0
- package/dist/modules/startup/errors/startup-errors.d.ts +13 -0
- package/dist/modules/startup/errors/startup-errors.d.ts.map +1 -0
- package/dist/modules/startup/errors/startup-errors.js +25 -0
- package/dist/modules/startup/errors/startup-errors.js.map +1 -0
- package/dist/modules/startup/index.d.ts +5 -0
- package/dist/modules/startup/index.d.ts.map +1 -0
- package/dist/modules/startup/index.js +7 -0
- package/dist/modules/startup/index.js.map +1 -0
- package/dist/modules/startup/services/startup-service.d.ts +7 -0
- package/dist/modules/startup/services/startup-service.d.ts.map +1 -0
- package/dist/modules/startup/services/startup-service.js +43 -0
- package/dist/modules/startup/services/startup-service.js.map +1 -0
- package/dist/modules/startup/types/startup-types.d.ts +8 -0
- package/dist/modules/startup/types/startup-types.d.ts.map +1 -0
- package/dist/modules/startup/types/startup-types.js +2 -0
- package/dist/modules/startup/types/startup-types.js.map +1 -0
- package/dist/modules/startup/utils/startup-validators.d.ts +8 -0
- package/dist/modules/startup/utils/startup-validators.d.ts.map +1 -0
- package/dist/modules/startup/utils/startup-validators.js +17 -0
- package/dist/modules/startup/utils/startup-validators.js.map +1 -0
- package/dist/modules/workspace/commands/init-workspace.d.ts +3 -0
- package/dist/modules/workspace/commands/init-workspace.d.ts.map +1 -0
- package/dist/modules/workspace/commands/init-workspace.js +54 -0
- package/dist/modules/workspace/commands/init-workspace.js.map +1 -0
- package/dist/modules/workspace/errors/workspace-errors.d.ts +10 -0
- package/dist/modules/workspace/errors/workspace-errors.d.ts.map +1 -0
- package/dist/modules/workspace/errors/workspace-errors.js +19 -0
- package/dist/modules/workspace/errors/workspace-errors.js.map +1 -0
- package/dist/modules/workspace/index.d.ts +5 -0
- package/dist/modules/workspace/index.d.ts.map +1 -0
- package/dist/modules/workspace/index.js +7 -0
- package/dist/modules/workspace/index.js.map +1 -0
- package/dist/modules/workspace/services/workspace-service.d.ts +6 -0
- package/dist/modules/workspace/services/workspace-service.d.ts.map +1 -0
- package/dist/modules/workspace/services/workspace-service.js +46 -0
- package/dist/modules/workspace/services/workspace-service.js.map +1 -0
- package/dist/modules/workspace/types/workspace-types.d.ts +8 -0
- package/dist/modules/workspace/types/workspace-types.d.ts.map +1 -0
- package/dist/modules/workspace/types/workspace-types.js +2 -0
- package/dist/modules/workspace/types/workspace-types.js.map +1 -0
- package/dist/modules/workspace/utils/workspace-validators.d.ts +8 -0
- package/dist/modules/workspace/utils/workspace-validators.d.ts.map +1 -0
- package/dist/modules/workspace/utils/workspace-validators.js +17 -0
- package/dist/modules/workspace/utils/workspace-validators.js.map +1 -0
- package/dist/plugins/theme/package.json +32 -0
- package/dist/plugins/theme/plugin.json +9 -0
- package/dist/plugins/theme/src/generator.ts +92 -0
- package/dist/plugins/theme/src/utils/config-modifier.ts +142 -0
- package/dist/plugins/theme/src/utils/css-modifier.ts +89 -0
- package/dist/plugins/theme/templates/app/theme-test/page.tsx +156 -0
- package/dist/plugins/theme/templates/src/modules/theme/README.md +209 -0
- package/dist/plugins/theme/templates/src/modules/theme/config/brand.css +23 -0
- package/dist/plugins/theme/tsconfig.json +14 -0
- package/dist/plugins/theme/tsup.config.ts +10 -0
- package/dist/templates/startup/apps/.gitkeep +8 -0
- package/dist/templates/templates/startup/apps/.gitkeep +8 -0
- package/dist/templates/templates/workspace/.eslintignore +7 -0
- package/dist/templates/templates/workspace/.eslintrc.js +38 -0
- package/dist/templates/templates/workspace/.husky/pre-push +24 -0
- package/dist/templates/templates/workspace/.launch77/workspace.json +3 -0
- package/dist/templates/templates/workspace/.lintstagedrc.json +4 -0
- package/dist/templates/templates/workspace/.prettierrc +9 -0
- package/dist/templates/templates/workspace/README.md +62 -0
- package/dist/templates/templates/workspace/app-templates/.gitkeep +1 -0
- package/dist/templates/templates/workspace/apps/.gitkeep +1 -0
- package/dist/templates/templates/workspace/libraries/.gitkeep +1 -0
- package/dist/templates/templates/workspace/package.json +31 -0
- package/dist/templates/templates/workspace/plugins/.gitkeep +1 -0
- package/dist/templates/templates/workspace/tsconfig.json +22 -0
- package/dist/templates/templates/workspace/turbo.json +25 -0
- package/dist/templates/workspace/.launch77/workspace.json +3 -0
- package/dist/templates/workspace/README.md +62 -0
- package/dist/templates/workspace/app-templates/.gitkeep +1 -0
- package/dist/templates/workspace/apps/.gitkeep +1 -0
- package/dist/templates/workspace/libraries/.gitkeep +1 -0
- package/dist/templates/workspace/package.json +21 -0
- package/dist/templates/workspace/plugins/.gitkeep +1 -0
- package/dist/templates/workspace/tsconfig.json +22 -0
- package/dist/templates/workspace/turbo.json +25 -0
- package/dist/utils/launch77-context.d.ts +16 -0
- package/dist/utils/launch77-context.d.ts.map +1 -0
- package/dist/utils/launch77-context.js +111 -0
- package/dist/utils/launch77-context.js.map +1 -0
- package/dist/utils/launch77-validation.d.ts +17 -0
- package/dist/utils/launch77-validation.d.ts.map +1 -0
- package/dist/utils/launch77-validation.js +44 -0
- package/dist/utils/launch77-validation.js.map +1 -0
- package/dist/utils/monorepo.d.ts +19 -0
- package/dist/utils/monorepo.d.ts.map +1 -0
- package/dist/utils/monorepo.js +100 -0
- package/dist/utils/monorepo.js.map +1 -0
- package/dist/utils/validation.d.ts +32 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +92 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/version.d.ts +7 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +16 -0
- package/dist/utils/version.js.map +1 -0
- package/launch77-cli-1.2.0.tgz +0 -0
- package/package.json +48 -0
- package/src/cli.ts +34 -0
- package/src/infrastructure/filesystem.ts +69 -0
- package/src/infrastructure/npm.ts +18 -0
- package/src/infrastructure/template-engine.ts +48 -0
- package/src/infrastructure/template-generator.ts +26 -0
- package/src/infrastructure/template.ts +66 -0
- package/src/modules/app/commands/create-app.ts +60 -0
- package/src/modules/app/commands/delete-app.ts +123 -0
- package/src/modules/app/commands/generate-manifest.ts +75 -0
- package/src/modules/app/commands/validate-manifest.ts +78 -0
- package/src/modules/app/errors/app-errors.ts +41 -0
- package/src/modules/app/index.ts +16 -0
- package/src/modules/app/lib/manifest-schema.ts +65 -0
- package/src/modules/app/services/app-svc.ts +115 -0
- package/src/modules/app/services/manifest-svc.ts +144 -0
- package/src/modules/app/types/app-types.ts +27 -0
- package/src/modules/catalog/commands/generate.ts +115 -0
- package/src/modules/catalog/commands/scan.ts +48 -0
- package/src/modules/catalog/config/catalog-config.test.ts +404 -0
- package/src/modules/catalog/config/catalog-config.ts +130 -0
- package/src/modules/catalog/index.ts +9 -0
- package/src/modules/catalog/parsers/typescript-parser.ts +93 -0
- package/src/modules/catalog/scanners/metadata-extractor.ts +134 -0
- package/src/modules/catalog/scanners/metadata-validator.ts +67 -0
- package/src/modules/catalog/scanners/ui-component-scanner.ts +185 -0
- package/src/modules/catalog/schemas/catalog-ui-components.schema.json +145 -0
- package/src/modules/catalog/services/catalog-generator-svc.test.ts +233 -0
- package/src/modules/catalog/services/catalog-generator-svc.ts +124 -0
- package/src/modules/catalog/services/catalog-svc.ts +222 -0
- package/src/modules/catalog/types/catalog-types.ts +149 -0
- package/src/modules/catalog/utils/examples-generator.ts +68 -0
- package/src/modules/catalog/utils/quality-reporter.ts +76 -0
- package/src/modules/catalog/validators/component-name-validator.test.ts +233 -0
- package/src/modules/catalog/validators/component-name-validator.ts +43 -0
- package/src/modules/deploy/commands/deploy-init-action.ts +247 -0
- package/src/modules/deploy/commands/deploy-init.ts +19 -0
- package/src/modules/deploy/commands/deploy-logs-action.ts +135 -0
- package/src/modules/deploy/commands/deploy-logs.ts +20 -0
- package/src/modules/deploy/commands/deploy-status-action.ts +175 -0
- package/src/modules/deploy/commands/deploy-status.ts +16 -0
- package/src/modules/deploy/index.ts +7 -0
- package/src/modules/deploy/services/deploy-svc.ts +31 -0
- package/src/modules/deploy/utils/vercel-extended.ts +286 -0
- package/src/modules/plugin/commands/plugin-install.ts +51 -0
- package/src/modules/plugin/errors/plugin-errors.ts +44 -0
- package/src/modules/plugin/index.ts +14 -0
- package/src/modules/plugin/lib/launch77-workspace.code-workspace +14 -0
- package/src/modules/plugin/lib/plugin-registry.ts +59 -0
- package/src/modules/plugin/services/plugin-svc.ts +53 -0
- package/src/modules/plugin/types/plugin-types.ts +21 -0
- package/src/modules/startup/commands/create-startup.ts +53 -0
- package/src/modules/startup/errors/startup-errors.ts +23 -0
- package/src/modules/startup/index.ts +11 -0
- package/src/modules/startup/services/startup-service.ts +57 -0
- package/src/modules/startup/types/startup-types.ts +8 -0
- package/src/modules/startup/utils/startup-validators.ts +19 -0
- package/src/modules/workspace/commands/init-workspace.ts +63 -0
- package/src/modules/workspace/errors/workspace-errors.ts +16 -0
- package/src/modules/workspace/index.ts +11 -0
- package/src/modules/workspace/services/workspace-service.ts +59 -0
- package/src/modules/workspace/types/workspace-types.ts +8 -0
- package/src/modules/workspace/utils/workspace-validators.ts +19 -0
- package/src/utils/launch77-context.ts +152 -0
- package/src/utils/launch77-validation.ts +59 -0
- package/src/utils/monorepo.ts +137 -0
- package/src/utils/validation.ts +117 -0
- package/src/utils/version.ts +16 -0
- package/templates/startup/apps/.gitkeep +8 -0
- package/templates/workspace/.eslintignore +7 -0
- package/templates/workspace/.eslintrc.js +38 -0
- package/templates/workspace/.husky/pre-push +24 -0
- package/templates/workspace/.launch77/workspace.json +3 -0
- package/templates/workspace/.lintstagedrc.json +4 -0
- package/templates/workspace/.prettierrc +9 -0
- package/templates/workspace/README.md +62 -0
- package/templates/workspace/app-templates/.gitkeep +1 -0
- package/templates/workspace/apps/.gitkeep +1 -0
- package/templates/workspace/libraries/.gitkeep +1 -0
- package/templates/workspace/package.json +31 -0
- package/templates/workspace/plugins/.gitkeep +1 -0
- package/templates/workspace/tsconfig.json +22 -0
- package/templates/workspace/turbo.json +25 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import * as path from 'path'
|
|
3
|
+
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
import { Command } from 'commander'
|
|
6
|
+
|
|
7
|
+
import { ManifestService } from '../services/manifest-svc.js'
|
|
8
|
+
|
|
9
|
+
export function validateManifestCommand(): Command {
|
|
10
|
+
const command = new Command('app:validate-manifest')
|
|
11
|
+
.description('Validate a Launch77 manifest file')
|
|
12
|
+
.option('--path <folder>', 'Path to search for manifest (defaults to current directory)')
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
try {
|
|
15
|
+
const searchPath = options.path ? path.resolve(options.path) : process.cwd()
|
|
16
|
+
|
|
17
|
+
console.log(chalk.blue('š Searching for Launch77 manifest (.launch/app.json)...\n'))
|
|
18
|
+
|
|
19
|
+
const manifestService = new ManifestService()
|
|
20
|
+
const { manifest, manifestPath, appRoot } = await manifestService.loadManifest(searchPath)
|
|
21
|
+
|
|
22
|
+
console.log(chalk.green('ā
Valid manifest found!\n'))
|
|
23
|
+
console.log(chalk.gray('Path:'), manifestPath)
|
|
24
|
+
console.log(chalk.gray('App root:'), appRoot)
|
|
25
|
+
console.log()
|
|
26
|
+
console.log(chalk.cyan('Manifest details:'))
|
|
27
|
+
console.log(chalk.gray(' Schema version:'), manifest.schemaVersion)
|
|
28
|
+
console.log(chalk.gray(' App type:'), manifest.type)
|
|
29
|
+
console.log(chalk.gray(' Package:'), manifest.package)
|
|
30
|
+
|
|
31
|
+
if ('name' in manifest && manifest.name) {
|
|
32
|
+
console.log(chalk.gray(' Name:'), manifest.name)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Check if deployment field exists
|
|
36
|
+
if (manifest.deployment) {
|
|
37
|
+
console.log(chalk.gray(' Deployment platform:'), manifest.deployment.platform)
|
|
38
|
+
if (manifest.deployment.connected) {
|
|
39
|
+
console.log(chalk.gray(' Connected:'), 'Yes')
|
|
40
|
+
if (manifest.deployment.projectName) {
|
|
41
|
+
console.log(chalk.gray(' Project:'), manifest.deployment.projectName)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
console.log()
|
|
47
|
+
console.log(chalk.green('⨠Manifest validation successful!'))
|
|
48
|
+
|
|
49
|
+
// Exit with success code
|
|
50
|
+
process.exit(0)
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error(chalk.red('ā Manifest validation failed:\n'))
|
|
53
|
+
|
|
54
|
+
if (error instanceof Error) {
|
|
55
|
+
// If it's our formatted error with validation issues, print it as-is
|
|
56
|
+
if (error.message.includes('Manifest validation failed:')) {
|
|
57
|
+
console.error(error.message)
|
|
58
|
+
} else {
|
|
59
|
+
console.error(chalk.red(error.message))
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
console.error(chalk.red('Unknown error occurred'))
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log()
|
|
66
|
+
console.log(chalk.gray('To create a new manifest, use:'))
|
|
67
|
+
console.log(chalk.cyan(' launch77 create-app <type> <name>'))
|
|
68
|
+
console.log()
|
|
69
|
+
console.log(chalk.gray('Or create one manually at .launch/app.json following the schema at:'))
|
|
70
|
+
console.log(chalk.cyan(' launch77/cli/schemas/app.launch77.schema.json'))
|
|
71
|
+
|
|
72
|
+
// Exit with error code
|
|
73
|
+
process.exit(1)
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
return command
|
|
78
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export class AppAlreadyExistsError extends Error {
|
|
2
|
+
constructor(appName: string, appPath: string) {
|
|
3
|
+
super(`App ${appName} already exists at ${appPath}`)
|
|
4
|
+
this.name = 'AppAlreadyExistsError'
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class AppNotFoundError extends Error {
|
|
9
|
+
constructor(appName: string, expectedPath: string) {
|
|
10
|
+
super(`App '${appName}' does not exist at ${expectedPath}`)
|
|
11
|
+
this.name = 'AppNotFoundError'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class InvalidAppNameError extends Error {
|
|
16
|
+
constructor(appName: string, reason: string) {
|
|
17
|
+
super(`Invalid app name '${appName}': ${reason}`)
|
|
18
|
+
this.name = 'InvalidAppNameError'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class TemplateNotFoundError extends Error {
|
|
23
|
+
constructor(templateType: string) {
|
|
24
|
+
super(`Template not found for type: ${templateType}`)
|
|
25
|
+
this.name = 'TemplateNotFoundError'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class ManifestNotFoundError extends Error {
|
|
30
|
+
constructor(searchDir: string) {
|
|
31
|
+
super(`No Launch77 manifest found in ${searchDir} or any parent directory`)
|
|
32
|
+
this.name = 'ManifestNotFoundError'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class InvalidManifestError extends Error {
|
|
37
|
+
constructor(message: string) {
|
|
38
|
+
super(`Invalid manifest: ${message}`)
|
|
39
|
+
this.name = 'InvalidManifestError'
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Services
|
|
2
|
+
export { AppService } from './services/app-svc.js'
|
|
3
|
+
export { ManifestService } from './services/manifest-svc.js'
|
|
4
|
+
|
|
5
|
+
// Types
|
|
6
|
+
export type { CreateAppRequest, CreateAppResult, DeleteAppRequest, DeleteAppResult, AppType } from './types/app-types.js'
|
|
7
|
+
export type { AppManifest, DeploymentConfig } from './lib/manifest-schema.js'
|
|
8
|
+
|
|
9
|
+
// Errors
|
|
10
|
+
export { AppAlreadyExistsError, AppNotFoundError, InvalidAppNameError, TemplateNotFoundError, ManifestNotFoundError, InvalidManifestError } from './errors/app-errors.js'
|
|
11
|
+
|
|
12
|
+
// Commands
|
|
13
|
+
export { createAppCommand } from './commands/create-app.js'
|
|
14
|
+
export { deleteAppCommand } from './commands/delete-app.js'
|
|
15
|
+
export { generateManifestCommand } from './commands/generate-manifest.js'
|
|
16
|
+
export { validateManifestCommand } from './commands/validate-manifest.js'
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import type { AppType } from '../types/app-types.js'
|
|
4
|
+
|
|
5
|
+
// Deployment configuration
|
|
6
|
+
export type DeploymentConfig = {
|
|
7
|
+
platform: 'vercel'
|
|
8
|
+
connected: boolean
|
|
9
|
+
connectedAt?: string
|
|
10
|
+
projectName?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// App manifest
|
|
14
|
+
export type AppManifest = {
|
|
15
|
+
schemaVersion: 1
|
|
16
|
+
name: string
|
|
17
|
+
type: AppType | 'marketing' // Support both 'marketing' and 'marketing-site'
|
|
18
|
+
package: string
|
|
19
|
+
deployment?: DeploymentConfig
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Zod schemas
|
|
23
|
+
const deploymentConfigZ = z.object({
|
|
24
|
+
platform: z.literal('vercel'),
|
|
25
|
+
connected: z.boolean(),
|
|
26
|
+
connectedAt: z.string().optional(),
|
|
27
|
+
projectName: z.string().optional(),
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// Main manifest schema - strict mode to reject extra fields
|
|
31
|
+
// Note: Manifests store 'marketing' but we accept 'marketing-site' in commands
|
|
32
|
+
export const manifestZ = z
|
|
33
|
+
.object({
|
|
34
|
+
schemaVersion: z.literal(1),
|
|
35
|
+
name: z.string().min(1),
|
|
36
|
+
type: z.enum(['marketing', 'webapp', 'api']),
|
|
37
|
+
package: z.string().min(1),
|
|
38
|
+
deployment: deploymentConfigZ.optional(),
|
|
39
|
+
})
|
|
40
|
+
.strict()
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Parse and validate a manifest from unknown JSON data
|
|
44
|
+
* @param json - Unknown JSON data to parse
|
|
45
|
+
* @returns Validated AppManifest
|
|
46
|
+
* @throws ZodError with aggregated error messages
|
|
47
|
+
*/
|
|
48
|
+
export function parseManifest(json: unknown): AppManifest {
|
|
49
|
+
try {
|
|
50
|
+
return manifestZ.parse(json) as AppManifest
|
|
51
|
+
} catch (error) {
|
|
52
|
+
if (error instanceof z.ZodError) {
|
|
53
|
+
// Format error messages nicely
|
|
54
|
+
const errorMessages = error.issues
|
|
55
|
+
.map((err: z.ZodIssue) => {
|
|
56
|
+
const path = err.path.join('.')
|
|
57
|
+
return ` - ${path ? `${path}: ` : ''}${err.message}`
|
|
58
|
+
})
|
|
59
|
+
.join('\n')
|
|
60
|
+
|
|
61
|
+
throw new Error(`Manifest validation failed:\n${errorMessages}`)
|
|
62
|
+
}
|
|
63
|
+
throw error
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import * as path from 'path'
|
|
2
|
+
|
|
3
|
+
import fs from 'fs-extra'
|
|
4
|
+
|
|
5
|
+
import { ManifestService } from './manifest-svc.js'
|
|
6
|
+
import * as filesystem from '../../../infrastructure/filesystem.js'
|
|
7
|
+
import * as npm from '../../../infrastructure/npm.js'
|
|
8
|
+
import { generateFromTemplate } from '../../../infrastructure/template-generator.js'
|
|
9
|
+
import { templateExists } from '../../../infrastructure/template.js'
|
|
10
|
+
import { validateWorkspaceContext } from '../../../utils/launch77-validation.js'
|
|
11
|
+
import { validateAppName } from '../../../utils/validation.js'
|
|
12
|
+
|
|
13
|
+
import type { Launch77Context } from '../../../utils/launch77-context.js'
|
|
14
|
+
import type { CreateAppRequest, CreateAppResult, DeleteAppRequest, DeleteAppResult } from '../types/app-types.js'
|
|
15
|
+
|
|
16
|
+
export class AppService {
|
|
17
|
+
private manifestService: ManifestService
|
|
18
|
+
|
|
19
|
+
constructor() {
|
|
20
|
+
this.manifestService = new ManifestService()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Create a new app from template
|
|
25
|
+
*/
|
|
26
|
+
async createApp(request: CreateAppRequest, context: Launch77Context): Promise<CreateAppResult> {
|
|
27
|
+
const { type, appName, port } = request
|
|
28
|
+
|
|
29
|
+
// 1. Validate app name
|
|
30
|
+
const nameValidation = validateAppName(appName)
|
|
31
|
+
if (!nameValidation.valid) {
|
|
32
|
+
throw new Error(nameValidation.errorMessage)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 2. Validate workspace context
|
|
36
|
+
const contextValidation = validateWorkspaceContext(context)
|
|
37
|
+
if (!contextValidation.valid) {
|
|
38
|
+
throw new Error(contextValidation.errorMessage)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 3. Determine app path
|
|
42
|
+
const appPath = path.join(context.appsDir, appName)
|
|
43
|
+
|
|
44
|
+
// 4. Check if app already exists
|
|
45
|
+
if (await fs.pathExists(appPath)) {
|
|
46
|
+
throw new Error(`App ${appName} already exists at ${appPath}`)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 5. Validate template exists
|
|
50
|
+
if (!(await templateExists(type))) {
|
|
51
|
+
throw new Error(`Unknown app type: ${type}. Currently supported: api, webapp, marketing-site`)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 6. Generate from template (context already has packageName computed)
|
|
55
|
+
await generateFromTemplate(type, appPath, appName, context, { port })
|
|
56
|
+
|
|
57
|
+
// 7. Generate and write app manifest
|
|
58
|
+
const manifest = this.manifestService.generateManifest(type, appName, context, { port })
|
|
59
|
+
const launchDir = path.join(appPath, '.launch')
|
|
60
|
+
await filesystem.ensureDir(launchDir)
|
|
61
|
+
const manifestPath = path.join(launchDir, 'app.json')
|
|
62
|
+
await filesystem.writeJSON(manifestPath, manifest)
|
|
63
|
+
|
|
64
|
+
// 8. Install dependencies
|
|
65
|
+
await npm.install(context.workspaceRoot)
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
appPath,
|
|
69
|
+
appName,
|
|
70
|
+
type,
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Delete an existing app
|
|
76
|
+
*/
|
|
77
|
+
async deleteApp(request: DeleteAppRequest, context: Launch77Context): Promise<DeleteAppResult> {
|
|
78
|
+
const { appName } = request
|
|
79
|
+
|
|
80
|
+
// 1. Validate app name
|
|
81
|
+
const nameValidation = validateAppName(appName)
|
|
82
|
+
if (!nameValidation.valid) {
|
|
83
|
+
throw new Error(nameValidation.errorMessage)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 2. Validate workspace context
|
|
87
|
+
const contextValidation = validateWorkspaceContext(context)
|
|
88
|
+
if (!contextValidation.valid) {
|
|
89
|
+
throw new Error(contextValidation.errorMessage)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 3. Determine app path
|
|
93
|
+
const appPath = path.join(context.appsDir, appName)
|
|
94
|
+
|
|
95
|
+
// 4. Check if app exists
|
|
96
|
+
if (!(await fs.pathExists(appPath))) {
|
|
97
|
+
throw new Error(`App '${appName}' does not exist.\n\n` + `Expected location: ${appPath}\n\n` + `Available apps:\n` + ` cd apps/\n` + ` ls`)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 5. Check for Docker resources
|
|
101
|
+
const dockerComposePath = path.join(appPath, 'docker-compose.db.yml')
|
|
102
|
+
const hasDockerResources = await fs.pathExists(dockerComposePath)
|
|
103
|
+
|
|
104
|
+
// 6. Delete the app directory
|
|
105
|
+
await fs.remove(appPath)
|
|
106
|
+
|
|
107
|
+
// 7. Update dependencies
|
|
108
|
+
await npm.install(context.workspaceRoot)
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
appName,
|
|
112
|
+
hadDockerResources: hasDockerResources,
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import * as fs from 'fs/promises'
|
|
2
|
+
import * as path from 'path'
|
|
3
|
+
|
|
4
|
+
import { parseManifest } from '../lib/manifest-schema.js'
|
|
5
|
+
|
|
6
|
+
import type { Launch77Context } from '../../../utils/launch77-context.js'
|
|
7
|
+
import type { AppManifest } from '../lib/manifest-schema.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Convert kebab-case to Title Case
|
|
11
|
+
* e.g., "my-startup-name" -> "My Startup Name"
|
|
12
|
+
*/
|
|
13
|
+
function toTitleCase(str: string): string {
|
|
14
|
+
return str
|
|
15
|
+
.split('-')
|
|
16
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
17
|
+
.join(' ')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Generate a manifest for a marketing app
|
|
22
|
+
*/
|
|
23
|
+
function generateMarketingManifest(appName: string, context: Launch77Context): AppManifest {
|
|
24
|
+
const workspaceName = context.workspaceName
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
schemaVersion: 1,
|
|
28
|
+
name: `${toTitleCase(workspaceName)} Marketing`,
|
|
29
|
+
type: 'marketing',
|
|
30
|
+
package: `@${workspaceName}/${appName}`,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Generate a manifest for a webapp
|
|
36
|
+
*/
|
|
37
|
+
function generateWebappManifest(appName: string, context: Launch77Context): AppManifest {
|
|
38
|
+
const workspaceName = context.workspaceName
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
schemaVersion: 1,
|
|
42
|
+
name: `${toTitleCase(workspaceName)} Web`,
|
|
43
|
+
type: 'webapp',
|
|
44
|
+
package: `@${workspaceName}/${appName}`,
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Generate a manifest for an API app
|
|
50
|
+
*/
|
|
51
|
+
function generateApiManifest(appName: string, context: Launch77Context): AppManifest {
|
|
52
|
+
const workspaceName = context.workspaceName
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
schemaVersion: 1,
|
|
56
|
+
name: `${toTitleCase(workspaceName)} API`,
|
|
57
|
+
type: 'api',
|
|
58
|
+
package: `@${workspaceName}/${appName}`,
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class ManifestService {
|
|
63
|
+
/**
|
|
64
|
+
* Generate an app manifest based on app type
|
|
65
|
+
*/
|
|
66
|
+
generateManifest(type: string, appName: string, context: Launch77Context, _options: { port?: string }): AppManifest {
|
|
67
|
+
switch (type) {
|
|
68
|
+
case 'marketing-site':
|
|
69
|
+
case 'marketing':
|
|
70
|
+
return generateMarketingManifest(appName, context)
|
|
71
|
+
|
|
72
|
+
case 'webapp':
|
|
73
|
+
return generateWebappManifest(appName, context)
|
|
74
|
+
|
|
75
|
+
case 'api':
|
|
76
|
+
return generateApiManifest(appName, context)
|
|
77
|
+
|
|
78
|
+
default:
|
|
79
|
+
throw new Error(`Unsupported app type for manifest generation: ${type}. Supported types: api, webapp, marketing-site`)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Load and validate a Launch77 app manifest file
|
|
85
|
+
* @param startDir - Directory to start searching from (defaults to process.cwd())
|
|
86
|
+
* @returns Object containing manifest, manifestPath, and appRoot
|
|
87
|
+
* @throws Error if manifest not found or invalid
|
|
88
|
+
*/
|
|
89
|
+
async loadManifest(startDir?: string): Promise<{
|
|
90
|
+
manifest: AppManifest
|
|
91
|
+
manifestPath: string
|
|
92
|
+
appRoot: string
|
|
93
|
+
}> {
|
|
94
|
+
const searchDir = startDir || process.cwd()
|
|
95
|
+
let currentDir = path.resolve(searchDir)
|
|
96
|
+
const root = path.parse(currentDir).root
|
|
97
|
+
|
|
98
|
+
// Walk up the directory tree looking for .launch/app.json
|
|
99
|
+
while (currentDir !== root) {
|
|
100
|
+
const manifestPath = path.join(currentDir, '.launch', 'app.json')
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
const fileContent = await fs.readFile(manifestPath, 'utf-8')
|
|
104
|
+
const jsonData = JSON.parse(fileContent)
|
|
105
|
+
const manifest = parseManifest(jsonData)
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
manifest,
|
|
109
|
+
manifestPath,
|
|
110
|
+
appRoot: currentDir,
|
|
111
|
+
}
|
|
112
|
+
} catch (error) {
|
|
113
|
+
// If file doesn't exist, continue searching up
|
|
114
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
115
|
+
const parentDir = path.dirname(currentDir)
|
|
116
|
+
if (parentDir === currentDir) {
|
|
117
|
+
break // Reached root
|
|
118
|
+
}
|
|
119
|
+
currentDir = parentDir
|
|
120
|
+
continue
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// If JSON parse error or validation error, throw with helpful message
|
|
124
|
+
if (error instanceof SyntaxError) {
|
|
125
|
+
throw new Error(`Invalid JSON in ${manifestPath}: ${error.message}`)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Re-throw validation errors as-is
|
|
129
|
+
throw error
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
throw new Error(`No Launch77 manifest found in ${searchDir} or any parent directory.\n` + `Looking for .launch/app.json.\n` + `Create one using 'launch77 create-app' or manually add a .launch/app.json file.`)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Save a manifest file
|
|
138
|
+
* @param manifestPath - Path to save the manifest
|
|
139
|
+
* @param manifest - Manifest data to save
|
|
140
|
+
*/
|
|
141
|
+
async saveManifest(manifestPath: string, manifest: AppManifest): Promise<void> {
|
|
142
|
+
await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8')
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Supported app types
|
|
2
|
+
export const APP_TYPES = ['api', 'webapp', 'marketing-site'] as const
|
|
3
|
+
export type AppType = (typeof APP_TYPES)[number]
|
|
4
|
+
|
|
5
|
+
// Display list for error messages
|
|
6
|
+
export const APP_TYPES_LIST = APP_TYPES.join(', ')
|
|
7
|
+
|
|
8
|
+
export interface CreateAppRequest {
|
|
9
|
+
type: AppType
|
|
10
|
+
appName: string
|
|
11
|
+
port: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface CreateAppResult {
|
|
15
|
+
appPath: string
|
|
16
|
+
appName: string
|
|
17
|
+
type: AppType
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface DeleteAppRequest {
|
|
21
|
+
appName: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface DeleteAppResult {
|
|
25
|
+
appName: string
|
|
26
|
+
hadDockerResources: boolean
|
|
27
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI command for generating catalog metadata files
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import path from 'path'
|
|
6
|
+
|
|
7
|
+
import chalk from 'chalk'
|
|
8
|
+
import { Command } from 'commander'
|
|
9
|
+
import ora from 'ora'
|
|
10
|
+
|
|
11
|
+
import { readCatalogConfig } from '../config/catalog-config.js'
|
|
12
|
+
import { CatalogGeneratorService } from '../services/catalog-generator-svc.js'
|
|
13
|
+
import { printQualityReport } from '../utils/quality-reporter.js'
|
|
14
|
+
|
|
15
|
+
interface GenerateOptions {
|
|
16
|
+
library: string
|
|
17
|
+
config: string
|
|
18
|
+
strict?: boolean
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Create the catalog:generate command
|
|
23
|
+
*/
|
|
24
|
+
export function createGenerateCommand(): Command {
|
|
25
|
+
const command = new Command('catalog:generate')
|
|
26
|
+
.description('Generate catalog metadata for a component library')
|
|
27
|
+
.option('-l, --library <path>', 'Library directory path', process.cwd())
|
|
28
|
+
.option('-c, --config <file>', 'Config file name', 'catalog.config.js')
|
|
29
|
+
.option('--no-strict', 'Allow generation with validation errors (warnings only)')
|
|
30
|
+
.action(async (options: GenerateOptions) => {
|
|
31
|
+
try {
|
|
32
|
+
await generateCatalog(options)
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error(chalk.red('\\nā Catalog generation failed\\n'))
|
|
35
|
+
if (error instanceof Error) {
|
|
36
|
+
console.error(chalk.red(error.message))
|
|
37
|
+
} else {
|
|
38
|
+
console.error(chalk.red(String(error)))
|
|
39
|
+
}
|
|
40
|
+
process.exit(1)
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
return command
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Execute catalog generation
|
|
49
|
+
*/
|
|
50
|
+
async function generateCatalog(options: GenerateOptions): Promise<void> {
|
|
51
|
+
const libraryPath = path.resolve(options.library)
|
|
52
|
+
|
|
53
|
+
console.log(chalk.blue('\\nš Generating catalog metadata...\\n'))
|
|
54
|
+
console.log(chalk.gray('Library: ' + libraryPath))
|
|
55
|
+
console.log(chalk.gray('Config: ' + options.config + '\\n'))
|
|
56
|
+
|
|
57
|
+
// Read and validate configuration
|
|
58
|
+
const spinner = ora('Reading configuration...').start()
|
|
59
|
+
|
|
60
|
+
let config
|
|
61
|
+
try {
|
|
62
|
+
config = await readCatalogConfig(libraryPath)
|
|
63
|
+
spinner.succeed('Configuration loaded')
|
|
64
|
+
} catch (error) {
|
|
65
|
+
spinner.fail('Failed to load configuration')
|
|
66
|
+
throw error
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Override strict mode if --no-strict flag provided
|
|
70
|
+
if (options.strict === false) {
|
|
71
|
+
config.validation.strict = false
|
|
72
|
+
console.log(chalk.yellow('ā Running in non-strict mode (validation errors will not fail build)\\n'))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Display configuration
|
|
76
|
+
console.log(chalk.gray('Configuration:'))
|
|
77
|
+
console.log(chalk.gray(' Package: ' + config.packageName))
|
|
78
|
+
console.log(chalk.gray(' Catalog version: ' + config.catalogVersion))
|
|
79
|
+
console.log(chalk.gray(' Output file: ' + config.outputFile))
|
|
80
|
+
console.log(chalk.gray(' Strict mode: ' + (config.validation.strict ? 'enabled' : 'disabled') + '\\n'))
|
|
81
|
+
|
|
82
|
+
// Generate catalog
|
|
83
|
+
const generationSpinner = ora('Scanning components...').start()
|
|
84
|
+
|
|
85
|
+
const service = new CatalogGeneratorService()
|
|
86
|
+
const result = await service.generateForLibrary(libraryPath, config)
|
|
87
|
+
|
|
88
|
+
generationSpinner.stop()
|
|
89
|
+
|
|
90
|
+
// Display quality report
|
|
91
|
+
console.log(chalk.blue('\\nš Quality Report\\n'))
|
|
92
|
+
printQualityReport(result.qualityReport, config.validation.strict)
|
|
93
|
+
|
|
94
|
+
// Handle result
|
|
95
|
+
if (!result.success) {
|
|
96
|
+
console.log(chalk.red('\\nā Catalog generation failed\\n'))
|
|
97
|
+
console.log(chalk.red('Validation errors must be fixed before building.'))
|
|
98
|
+
console.log(chalk.gray('\\nTo fix:'))
|
|
99
|
+
console.log(chalk.gray(' 1. Add @launch77-component JSDoc to components listed above'))
|
|
100
|
+
console.log(chalk.gray(' 2. Or add @launch77-ignore to exclude internal/WIP components'))
|
|
101
|
+
console.log(chalk.gray(' 3. Or run with --no-strict to allow warnings\\n'))
|
|
102
|
+
process.exit(1)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Success!
|
|
106
|
+
console.log(chalk.green('\\nā Generated ' + config.outputFile))
|
|
107
|
+
console.log(chalk.gray(' Quality score: ' + result.qualityReport.qualityScore + '%'))
|
|
108
|
+
console.log(chalk.gray(' Total components: ' + result.qualityReport.totalComponents))
|
|
109
|
+
|
|
110
|
+
if (result.warnings.length > 0) {
|
|
111
|
+
console.log(chalk.yellow(' Warnings: ' + result.warnings.length))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log()
|
|
115
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import chalk from 'chalk'
|
|
2
|
+
import { Command } from 'commander'
|
|
3
|
+
|
|
4
|
+
import { detectMonorepoContext } from '../../../utils/monorepo.js'
|
|
5
|
+
import { CatalogService } from '../services/catalog-svc.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Scan command - Generate catalog.json from Launch77 artifacts
|
|
9
|
+
*
|
|
10
|
+
* Scans UI components, libraries, plugins, and utilities from the Launch77 monorepo
|
|
11
|
+
* and generates a machine-readable catalog for AI discovery.
|
|
12
|
+
*/
|
|
13
|
+
export function scanCommand(): Command {
|
|
14
|
+
const command = new Command('catalog:scan')
|
|
15
|
+
.description('Scan Launch77 artifacts and generate catalog.json')
|
|
16
|
+
.option('--no-strict', 'Skip validation errors and generate catalog anyway')
|
|
17
|
+
.option('--quiet', 'Suppress quality report output')
|
|
18
|
+
.action(async (options) => {
|
|
19
|
+
try {
|
|
20
|
+
const context = await detectMonorepoContext(process.cwd())
|
|
21
|
+
|
|
22
|
+
if (!context.isValid) {
|
|
23
|
+
console.error(chalk.red('\nā Must be run from within a Launch77 monorepo\n'))
|
|
24
|
+
process.exit(1)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const catalogService = new CatalogService()
|
|
28
|
+
|
|
29
|
+
await catalogService.scanCatalog(context, {
|
|
30
|
+
strict: options.strict,
|
|
31
|
+
quiet: options.quiet,
|
|
32
|
+
})
|
|
33
|
+
} catch (error) {
|
|
34
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
35
|
+
|
|
36
|
+
if (message.includes('validation failed')) {
|
|
37
|
+
console.log(chalk.red('\nā Catalog validation failed in strict mode.\n'))
|
|
38
|
+
console.log(chalk.yellow('Fix validation errors or use --no-strict flag to generate catalog anyway.\n'))
|
|
39
|
+
} else {
|
|
40
|
+
console.error(chalk.red(`\nā Error: ${message}\n`))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
process.exit(1)
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
return command
|
|
48
|
+
}
|