Skip to content

Commit

Permalink
[V15] Updated dotnet template for Umbraco Packages with Bellisima (#1…
Browse files Browse the repository at this point in the history
…7108)

* [WIP] Create Umbraco/Bellissima Package

* Removes existing 'UmbracoPackage'

This is because the RCL based one will be the only one going forward

* Rename existing UmbracoPackageRCL to UmbracoPackage

* Drop the mentions of RCL in the identifiers

* CodeQL GitHub Action is complaining due to V15 wanting v9 .NET

* Rename UmbracoPackage template to UmbracoExtension

As this will only scaffold an extension and not other bits for a package such as Nuget, Github Actions & other things needed to be done to ship out a package

* Remove package lock as npm install by the OS should generate this and can differ between Windows, Linux/OSX

* Move JS clientside stuff into a folder called Client

Will allow us to ignore the folder if or when doing a dotnet pack with a rule in CSProj

* Add in .VSCode recommened extensions file to get the useful Lit Extension for completions in VSCode

* For now remove the example dashboard & prop editor

* Add a simple entrypoint

* Fix path for primary output after rename

* Use link suggested from Lotte

* Use backofficeEntryPoint as entryPoint is deprecated

* Update the umbraco-package.json to opt into telemetry as per PR suggestion

* Improve commented code to include a link to docs

* Improve readme from suggestions

* Updates package.json to use latest Vite & TS

Copies the tsconfig from the default scaffolding of vite lit-ts CLI

* Adds the base property suggestion from Jacob & puts in a comment as to what its used for

* Work in progress from hackathon day/afternoon

* Hey-API generating a HTTP Client had changed and was a PITA to figure out what had changed

Things to do for next time:
Include these files if they include --include-samples flag

* constants.ts
* Controllers/
* Composers/
* client/src/api
* client/src/dashboards/
* client/src/entrypoints

Change file contents
* client/src/bundle.manifests.ts
* client/src/package.json (extra dependencies)

* Adds in new property/flag/switch for dotnet new template

* Warren cant spell Whether 🙈

* Update template.json to exclude the sample files if flag is not set/false

* Make SLN happy/build

* Conditional content in files for IncludeExample flag/switch

* Need to include the content otherwise it doesnt get packed by nuget

* Fix the path for the openapi-ts-config.ts file to be included/excluded

* Use the project name from the dotnet new to help name manifests

* Update namespaces so they get updated when dotnet new templatge is run with the --name

* Updated example

* Fix up VS Code recommended extension for Lit VSCode

Should be .json not a .ts

* Fix up build - as we dont use the imported UmbCurrentUserContext

* Remove the relative path to the JSON schema as unable to know path to the web project

* Typo fix as spooted by Rich

* Update templates/UmbracoExtension/.template.config/template.json

Co-authored-by: Lotte Pitcher <LottePitcher@users.noreply.github.com>

* Adds a --site-domain flag/switch to use for setting the domain prefix

Sets a default value of https://localhost:5000
We have no way of knowing what URL/domain the site is running at for the Umbraco website project

* Rename stuff so its not 'example' & only have ping if include-examples is not set

* As agreed with Lotte makes sense we always generate OpenAPI & TS client

* Update umbraco-extension description

* Generic node script to generate the TS client

Checks if it can connect to it first and prompts user to ensure Umbraco site running or perhaps they need to change the URL in package.json for the node script

* Generated API has conditional stuff in now to have just Ping or the more examples based on switch/flag

* Adds symbols safeNamespace and safeName

safeNamespace uses the one built in and then safeName, depends on the cleaned namespace to then use a custom transform (forms) to then use a regex replace on . and _ to ensure we have a nicer name still for namespaces, class names, URL/routes for the swagger etc...

* change to use Umbraco.Extension as sourcename - check \.template.config\readme.md for 'placeholder' guidance

* use '-sd' as shortname for site-domain as otherwise shows up as '-p:d'

* fix typescript build error  when not including examples

* use provided name for API description as always being added

* Missing renames of Contrioller stuff with Lotte @ hackathon

* We missed the ctor

* Titlecase the API URLs for Swagger/API Controller

* dashboard tweaks

* Missing [Server] on Whats the Time Modal/UUI-box

---------

Co-authored-by: leekelleher <leekelleher@gmail.com>
Co-authored-by: Lotte Pitcher <LottePitcher@users.noreply.github.com>
Co-authored-by: Lotte Pitcher <github@lottepitcher.co.uk>
  • Loading branch information
4 people authored Nov 8, 2024
1 parent 79059d6 commit 2f4b198
Show file tree
Hide file tree
Showing 35 changed files with 1,375 additions and 313 deletions.
12 changes: 9 additions & 3 deletions templates/Umbraco.Templates.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@
<Link>UmbracoProject\Program.cs</Link>
<PackagePath>UmbracoProject</PackagePath>
</Content>
<Content Include="UmbracoPackage\**" Exclude="bin;obj" />
<Content Include="UmbracoPackageRcl\**" Exclude="bin;obj" />
<Content Include="UmbracoProject\**" Exclude="bin;obj" />
<Content Include="UmbracoDockerCompose\**" Exclude="bin;obj"/>
<Content Include="UmbracoExtension\**" Exclude="bin;obj" />
<Content Include="UmbracoDockerCompose\**" Exclude="bin;obj" />
<Content Include="..\src\Umbraco.Web.UI\Views\Partials\blocklist\**">
<Link>UmbracoProject\Views\Partials\blocklist\%(RecursiveDir)%(Filename)%(Extension)</Link>
<PackagePath>UmbracoProject\Views\Partials\blocklist</PackagePath>
Expand All @@ -40,6 +39,13 @@
<ItemGroup>
<Content Update="**\.template.config\template.json" Pack="false" />
</ItemGroup>
<!-- Added project references as the sample API in umbraco-extension will fail -->
<ItemGroup>
<ProjectReference Include="..\src\Umbraco.Cms.Api.Common\Umbraco.Cms.Api.Common.csproj" />
<ProjectReference Include="..\src\Umbraco.Cms.Api.Management\Umbraco.Cms.Api.Management.csproj" />
<ProjectReference Include="..\src\Umbraco.Web.Common\Umbraco.Web.Common.csproj" />
<ProjectReference Include="..\src\Umbraco.Web.Website\Umbraco.Web.Website.csproj" />
</ItemGroup>
<Target Name="GetUpdatedTemplateJsonPackageFiles" BeforeTargets="GenerateNuspec" AfterTargets="GetUmbracoBuildVersion">
<ItemGroup>
<_TemplateJsonFiles Include="**\.template.config\template.json" Exclude="bin\**;obj\**" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
"SupportPagesAndViews": {
"longName": "support-pages-and-views",
"shortName": "s"
},
"IncludeExample": {
"longName": "include-example",
"shortName": "ex"
},
"SiteDomain": {
"longName": "site-domain",
"shortName": "sd"
}
}
}
35 changes: 35 additions & 0 deletions templates/UmbracoExtension/.template.config/ide.host.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"$schema": "https://json.schemastore.org/ide.host.json",
"order": 0,
"icon": "../../icon.png",
"description": {
"id": "umbraco-extension",
"text": "Umbraco Extension - A Razor Class Library project for building Umbraco extensions."
},
"symbolInfo": [
{
"id": "UmbracoVersion",
"isVisible": true
},
{
"id": "SupportPagesAndViews",
"isVisible": true,
"persistenceScope": "templateGroup"
},
{
"id": "IncludeExample",
"isVisible": true,
"description": {
"text": "Whether to include an example dashboard and supporting code"
}
},
{
"id": "SiteDomain",
"isVisible": true,
"defaultValue": "https://localhost:5000",
"description": {
"text": "If using the --include-example then you can supply the domain prefix such as 'https://localhost:5000' to communicate with the Umbraco website for generating the TypeScript OpenAPI client"
}
}
]
}
25 changes: 25 additions & 0 deletions templates/UmbracoExtension/.template.config/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Customising the umbraco-extension template

## Source Name

The source name is set to `Umbraco.Extension`

The templating engine will rename any folder or file whose name contains `Umbraco.Extension` replacing it with the provided name.

The templating engine will replace the text in any file as follows:

- `Umbraco.Extension` with the safe namespace for the provided name
- `Umbraco_Extension` with the safe default class name for the provided name
- `umbraco.extension` with the safe namespace for the provided name, in lower case
- `umbraco_extension` with the safe default class name for the provided name, in lower case

## Custom Replacements

The following custom placeholders have been configured in `template.json`:

- `UmbracoExtension` will be replaced with the safe namespace but without . or _
- `umbracoextension` will be replaced with the safe namespace but without . or _ , in lower case
- `umbraco-extension` will be replaced with the kebab case transform of the provided name
- `Umbraco Extension` will be replaced with a 'friendly' version of the provided name, e.g. MyProject > My Project. NB it will render a trailing space so you don't need to add one.

The first three custom placeholders have been configured to replace the text in both files and filenames.
170 changes: 170 additions & 0 deletions templates/UmbracoExtension/.template.config/template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
{
"$schema": "https://json.schemastore.org/template.json",
"author": "Umbraco HQ",
"classifications": [
"Web",
"CMS",
"Umbraco",
"Extension",
"Plugin",
"Razor Class Library"
],
"name": "Umbraco Extension",
"description": "A Razor Class Library project for building Umbraco extensions.",
"groupIdentity": "Umbraco.Templates.UmbracoExtension",
"identity": "Umbraco.Templates.UmbracoExtension",
"shortName": "umbraco-extension",
"tags": {
"language": "C#",
"type": "project"
},
"sourceName": "Umbraco.Extension",
"defaultName": "Umbraco.Extension",
"preferNameDirectory": true,
"symbols": {
"Framework": {
"displayName": "Framework",
"description": "The target framework for the project.",
"type": "parameter",
"datatype": "choice",
"choices": [
{
"displayName": ".NET 9.0",
"description": "Target net9.0",
"choice": "net9.0"
}
],
"defaultValue": "net9.0",
"replaces": "net9.0"
},
"UmbracoVersion": {
"displayName": "Umbraco version",
"description": "The version of Umbraco.Cms to add as PackageReference. By default it installs the latest non pre-release version",
"type": "parameter",
"datatype": "string",
"defaultValue": "*",
"replaces": "UMBRACO_VERSION_FROM_TEMPLATE"
},
"SkipRestore": {
"displayName": "Skip restore",
"description": "If specified, skips the automatic restore of the project on create.",
"type": "parameter",
"datatype": "bool",
"defaultValue": "false"
},
"SupportPagesAndViews": {
"type": "parameter",
"datatype": "bool",
"defaultValue": "false",
"displayName": "Support pages and views",
"description": "Whether to support adding traditional Razor pages and Views to this library."
},
"KebabCasedName": {
"type": "derived",
"valueSource": "name",
"replaces": "umbraco-extension",
"fileRename": "umbraco-extension",
"valueTransform": "kebabCase"
},
"SafeName": {
"type": "derived",
"valueSource": "name",
"valueTransform": "safe_namespace"
},
"SafeCleanName": {
"type": "derived",
"valueSource": "SafeName",
"replaces": "UmbracoExtension",
"fileRename": "UmbracoExtension",
"valueTransform": "removePunctuation"
},
"SafeCleanNameLower": {
"type": "derived",
"valueSource": "SafeCleanName",
"replaces": "umbracoextension",
"fileRename": "umbracoextension",
"valueTransform": "lowerCase"
},
"SafeCleanNameFriendly": {
"type": "derived",
"valueSource": "SafeCleanName",
"replaces": "Umbraco Extension",
"valueTransform": "pascalCaseToSpaces"
},
"IncludeExample": {
"displayName": "Include Example Code",
"description": "Whether to include an example dashboard and other code to get started with.",
"type": "parameter",
"datatype": "bool",
"defaultValue": "false"
},
"SiteDomain": {
"displayName": "Site Domain",
"description": "If using the --include-example then you can supply the domain prefix such as 'https://localhost:5000' to communicate with the Umbraco website for generating the TypeScript OpenAPI client",
"type": "parameter",
"datatype": "string",
"defaultValue": "https://localhost:5000",
"replaces": "https://localhost:44339"
}
},
"forms": {
"removePunctuation": {
"identifier": "replace",
"pattern": "[\\._]",
"replacement": ""
},
"pascalCaseToSpaces": {
"identifier": "replace",
"pattern": "([A-Z][a-z]+)",
"replacement": "$1 "
}
},
"primaryOutputs": [
{
"path": "Umbraco.Extension.csproj"
}
],
"postActions": [
{
"id": "restore",
"condition": "(!SkipRestore)",
"description": "Restore NuGet packages required by this project.",
"manualInstructions": [
{
"text": "Run 'dotnet restore'"
}
],
"actionId": "210D431B-A78B-4D2F-B762-4ED3E3EA9025",
"continueOnError": true
},
{
"actionId": "3A7C4B45-1F5D-4A30-959A-51B88E82B5D2",
"args": {
"executable": "powershell",
"args": "cd Client;npm install;npm run build;",
"redirectStandardError": false,
"redirectStandardOutput": false
},
"manualInstructions": [
{
"text": "From the 'Client' folder run 'npm install' and then 'npm run build'"
}
],
"continueOnError": true,
"description ": "Installs node modules"
}
],
"sources": [
{
"modifiers": [
{
"condition": "(!IncludeExample)",
"exclude": [
"[Cc]lient/src/dashboards/**",
"[Cc]lient/src/api/schemas.gen.ts"
]
}
]
}
]
}
5 changes: 5 additions & 0 deletions templates/UmbracoExtension/Client/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recommendations": [
"runem.lit-plugin"
]
}
21 changes: 21 additions & 0 deletions templates/UmbracoExtension/Client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "umbraco-extension",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"watch": "tsc && vite build --watch",
"build": "tsc && vite build",
"generate-client": "node scripts/generate-openapi.js https://localhost:44339/umbraco/swagger/umbracoextension/swagger.json"
},
"devDependencies": {
"@hey-api/client-fetch": "^0.4.2",
"@hey-api/openapi-ts": "^0.53.11",
"@umbraco-cms/backoffice": "^UMBRACO_VERSION_FROM_TEMPLATE",
"chalk": "^5.3.0",
"cross-env": "^7.0.3",
"node-fetch": "^3.3.2",
"typescript": "^5.6.3",
"vite": "^5.4.9"
}
}
14 changes: 14 additions & 0 deletions templates/UmbracoExtension/Client/public/umbraco-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "Umbraco.Extension",
"name": "Umbraco.Extension",
"version": "0.0.0",
"allowPackageTelemetry": true,
"extensions": [
{
"name": "Umbraco ExtensionBundle",
"alias": "Umbraco.Extension.Bundle",
"type": "bundle",
"js": "/App_Plugins/UmbracoExtension/umbraco-extension.js"
}
]
}
48 changes: 48 additions & 0 deletions templates/UmbracoExtension/Client/scripts/generate-openapi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import fetch from 'node-fetch';
import chalk from 'chalk';
import { createClient } from '@hey-api/openapi-ts';

// Start notifying user we are generating the TypeScript client
console.log(chalk.green("Generating OpenAPI client..."));

const swaggerUrl = process.argv[2];
if (swaggerUrl === undefined) {
console.error(chalk.red(`ERROR: Missing URL to OpenAPI spec`));
console.error(`Please provide the URL to the OpenAPI spec as the first argument found in ${chalk.yellow('package.json')}`);
console.error(`Example: node generate-openapi.js ${chalk.yellow('https://localhost:44331/umbraco/swagger/REPLACE_ME/swagger.json')}`);
process.exit();
}

// Needed to ignore self-signed certificates from running Umbraco on https on localhost
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

// Start checking to see if we can connect to the OpenAPI spec
console.log("Ensure your Umbraco instance is running");
console.log(`Fetching OpenAPI definition from ${chalk.yellow(swaggerUrl)}`);

fetch(swaggerUrl).then(response => {
if (!response.ok) {
console.error(chalk.red(`ERROR: OpenAPI spec returned with a non OK (200) response: ${response.status} ${response.statusText}`));
console.error(`The URL to your Umbraco instance may be wrong or the instance is not running`);
console.error(`Please verify or change the URL in the ${chalk.yellow('package.json')} for the script ${chalk.yellow('generate-openapi')}`);
return;
}

console.log(`OpenAPI spec fetched successfully`);
console.log(`Calling ${chalk.yellow('hey-api')} to generate TypeScript client`);

createClient({
client: '@hey-api/client-fetch',
input: swaggerUrl,
output: 'src/api',
services: {
asClass: true,
}
});

})
.catch(error => {
console.error(`ERROR: Failed to connect to the OpenAPI spec: ${chalk.red(error.message)}`);
console.error(`The URL to your Umbraco instance may be wrong or the instance is not running`);
console.error(`Please verify or change the URL in the ${chalk.yellow('package.json')} for the script ${chalk.yellow('generate-openapi')}`);
});
6 changes: 6 additions & 0 deletions templates/UmbracoExtension/Client/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// This file is auto-generated by @hey-api/openapi-ts
//#if(IncludeExample)
export * from './schemas.gen';
//#endif
export * from './services.gen';
export * from './types.gen';
Loading

0 comments on commit 2f4b198

Please sign in to comment.