Compare commits
6 Commits
18d50346a9
...
1b774c1de6
| Author | SHA1 | Date | |
|---|---|---|---|
|
1b774c1de6
|
|||
|
9b4cbade5c
|
|||
|
a52e54f672
|
|||
|
aa48d5e25d
|
|||
|
ce18b194a5
|
|||
|
382579a20e
|
4
.github/workflows/docker-build.yml
vendored
4
.github/workflows/docker-build.yml
vendored
@@ -27,8 +27,8 @@ jobs:
|
||||
run: |
|
||||
files="${{ steps.changed-files.outputs.files }}"
|
||||
matrix="{\"include\":[]}"
|
||||
services=("Sphere" "Pass" "Ring" "Drive" "Develop" "Gateway" "Insight")
|
||||
images=("sphere" "pass" "ring" "drive" "develop" "gateway" "insight")
|
||||
services=("Sphere" "Pass" "Ring" "Drive" "Develop" "Gateway" "Insight" "Zone")
|
||||
images=("sphere" "pass" "ring" "drive" "develop" "gateway" "insight" "zone")
|
||||
changed_services=()
|
||||
|
||||
for file in $files; do
|
||||
|
||||
@@ -26,11 +26,17 @@ var insightService = builder.AddProject<Projects.DysonNetwork_Insight>("insight"
|
||||
.WithReference(ringService)
|
||||
.WithReference(sphereService)
|
||||
.WithReference(developService);
|
||||
var zoneService = builder.AddProject<Projects.DysonNetwork_Zone>("zone")
|
||||
.WithReference(passService)
|
||||
.WithReference(ringService)
|
||||
.WithReference(sphereService)
|
||||
.WithReference(developService)
|
||||
.WithReference(insightService);
|
||||
|
||||
passService.WithReference(developService).WithReference(driveService);
|
||||
|
||||
List<IResourceBuilder<ProjectResource>> services =
|
||||
[ringService, passService, driveService, sphereService, developService, insightService];
|
||||
[ringService, passService, driveService, sphereService, developService, insightService, zoneService];
|
||||
|
||||
for (var idx = 0; idx < services.Count; idx++)
|
||||
{
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Sdk Name="Aspire.AppHost.Sdk" Version="13.0.0" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<UserSecretsId>a68b3195-a00d-40c2-b5ed-d675356b7cde</UserSecretsId>
|
||||
<RootNamespace>DysonNetwork.Control</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.0.0" />
|
||||
<PackageReference Include="Aspire.Hosting.Docker" Version="13.0.0-preview.1.25560.3" />
|
||||
<PackageReference Include="Aspire.Hosting.Nats" Version="13.0.0" />
|
||||
<PackageReference Include="Aspire.Hosting.Redis" Version="13.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DysonNetwork.Develop\DysonNetwork.Develop.csproj" />
|
||||
<ProjectReference Include="..\DysonNetwork.Drive\DysonNetwork.Drive.csproj" />
|
||||
<ProjectReference Include="..\DysonNetwork.Pass\DysonNetwork.Pass.csproj" />
|
||||
<ProjectReference Include="..\DysonNetwork.Ring\DysonNetwork.Ring.csproj" />
|
||||
<ProjectReference Include="..\DysonNetwork.Sphere\DysonNetwork.Sphere.csproj" />
|
||||
<ProjectReference Include="..\DysonNetwork.Gateway\DysonNetwork.Gateway.csproj" />
|
||||
<ProjectReference Include="..\DysonNetwork.Insight\DysonNetwork.Insight.csproj" />
|
||||
</ItemGroup>
|
||||
<Sdk Name="Aspire.AppHost.Sdk" Version="13.0.0"/>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<UserSecretsId>a68b3195-a00d-40c2-b5ed-d675356b7cde</UserSecretsId>
|
||||
<RootNamespace>DysonNetwork.Control</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.0.0"/>
|
||||
<PackageReference Include="Aspire.Hosting.Docker" Version="13.0.0-preview.1.25560.3"/>
|
||||
<PackageReference Include="Aspire.Hosting.Nats" Version="13.0.0"/>
|
||||
<PackageReference Include="Aspire.Hosting.Redis" Version="13.0.0"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DysonNetwork.Develop\DysonNetwork.Develop.csproj"/>
|
||||
<ProjectReference Include="..\DysonNetwork.Drive\DysonNetwork.Drive.csproj"/>
|
||||
<ProjectReference Include="..\DysonNetwork.Pass\DysonNetwork.Pass.csproj"/>
|
||||
<ProjectReference Include="..\DysonNetwork.Ring\DysonNetwork.Ring.csproj"/>
|
||||
<ProjectReference Include="..\DysonNetwork.Sphere\DysonNetwork.Sphere.csproj"/>
|
||||
<ProjectReference Include="..\DysonNetwork.Gateway\DysonNetwork.Gateway.csproj"/>
|
||||
<ProjectReference Include="..\DysonNetwork.Insight\DysonNetwork.Insight.csproj"/>
|
||||
<ProjectReference Include="..\DysonNetwork.Zone\DysonNetwork.Zone.csproj"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -14,7 +14,7 @@ public class SnPublicationSite : ModelBase
|
||||
public List<SnPublicationPage> Pages { get; set; } = [];
|
||||
|
||||
public Guid PublisherId { get; set; }
|
||||
public SnPublisher Publisher { get; set; } = null!;
|
||||
[NotMapped] public SnPublisher Publisher { get; set; } = null!;
|
||||
public Guid AccountId { get; set; }
|
||||
// Preloaded via the remote services
|
||||
[NotMapped] public SnAccount? Account { get; set; }
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
using NodaTime.Extensions;
|
||||
using NodaTime.Serialization.Protobuf;
|
||||
|
||||
namespace DysonNetwork.Shared.Models;
|
||||
@@ -148,23 +150,42 @@ public class SnPublisherMember : ModelBase
|
||||
public Instant? JoinedAt { get; set; }
|
||||
|
||||
|
||||
public Proto.PublisherMember ToProto()
|
||||
public PublisherMember ToProto()
|
||||
{
|
||||
return new Proto.PublisherMember()
|
||||
return new PublisherMember
|
||||
{
|
||||
PublisherId = PublisherId.ToString(),
|
||||
AccountId = AccountId.ToString(),
|
||||
Role = Role switch
|
||||
{
|
||||
PublisherMemberRole.Owner => Shared.Proto.PublisherMemberRole.Owner,
|
||||
PublisherMemberRole.Manager => Shared.Proto.PublisherMemberRole.Manager,
|
||||
PublisherMemberRole.Editor => Shared.Proto.PublisherMemberRole.Editor,
|
||||
PublisherMemberRole.Viewer => Shared.Proto.PublisherMemberRole.Viewer,
|
||||
PublisherMemberRole.Owner => Proto.PublisherMemberRole.Owner,
|
||||
PublisherMemberRole.Manager => Proto.PublisherMemberRole.Manager,
|
||||
PublisherMemberRole.Editor => Proto.PublisherMemberRole.Editor,
|
||||
PublisherMemberRole.Viewer => Proto.PublisherMemberRole.Viewer,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(Role), Role, null)
|
||||
},
|
||||
JoinedAt = JoinedAt?.ToTimestamp()
|
||||
};
|
||||
}
|
||||
|
||||
public static SnPublisherMember FromProtoValue(PublisherMember proto)
|
||||
{
|
||||
return new SnPublisherMember
|
||||
{
|
||||
PublisherId = Guid.Parse(proto.PublisherId),
|
||||
AccountId = Guid.Parse(proto.AccountId),
|
||||
Role = proto.Role switch
|
||||
{
|
||||
Proto.PublisherMemberRole.Owner => PublisherMemberRole.Owner,
|
||||
Proto.PublisherMemberRole.Manager => PublisherMemberRole.Manager,
|
||||
Proto.PublisherMemberRole.Editor => PublisherMemberRole.Editor,
|
||||
_ => PublisherMemberRole.Viewer
|
||||
},
|
||||
JoinedAt = proto.JoinedAt?.ToDateTimeOffset().ToInstant(),
|
||||
CreatedAt = proto.CreatedAt.ToDateTimeOffset().ToInstant(),
|
||||
UpdatedAt = proto.UpdatedAt.ToDateTimeOffset().ToInstant()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public enum PublisherSubscriptionStatus
|
||||
@@ -200,4 +221,4 @@ public abstract class PublisherFeatureFlag
|
||||
{
|
||||
public static List<string> AllFlags => [Develop];
|
||||
public static string Develop = "develop";
|
||||
}
|
||||
}
|
||||
|
||||
111
DysonNetwork.Shared/Registry/RemotePublisherService.cs
Normal file
111
DysonNetwork.Shared/Registry/RemotePublisherService.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
|
||||
namespace DysonNetwork.Shared.Registry;
|
||||
|
||||
public class RemotePublisherService(PublisherService.PublisherServiceClient publishers)
|
||||
{
|
||||
public async Task<SnPublisher> GetPublisher(string? name = null, string? id = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name) && string.IsNullOrEmpty(id))
|
||||
throw new ArgumentException("Either name or id must be provided.");
|
||||
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(id))
|
||||
throw new ArgumentException("Only one of name or id can be provided.");
|
||||
|
||||
var request = new GetPublisherRequest();
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
request.Name = name;
|
||||
else
|
||||
request.Id = id;
|
||||
|
||||
var response = await publishers.GetPublisherAsync(request, cancellationToken: cancellationToken);
|
||||
return SnPublisher.FromProtoValue(response.Publisher);
|
||||
}
|
||||
|
||||
public async Task<List<SnPublisher>> GetPublishersBatch(List<string> ids,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new GetPublisherBatchRequest();
|
||||
request.Ids.AddRange(ids);
|
||||
var response = await publishers.GetPublisherBatchAsync(request, cancellationToken: cancellationToken);
|
||||
return response.Publishers.Select(SnPublisher.FromProtoValue).ToList();
|
||||
}
|
||||
|
||||
public async Task<List<SnPublisher>> ListPublishers(string? accountId = null, string? realmId = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new ListPublishersRequest
|
||||
{
|
||||
AccountId = accountId ?? "",
|
||||
RealmId = realmId ?? ""
|
||||
};
|
||||
var response = await publishers.ListPublishersAsync(request, cancellationToken: cancellationToken);
|
||||
return response.Publishers.Select(SnPublisher.FromProtoValue).ToList();
|
||||
}
|
||||
|
||||
public async Task<List<SnPublisherMember>> ListPublisherMembers(string publisherId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new ListPublisherMembersRequest { PublisherId = publisherId };
|
||||
var response = await publishers.ListPublisherMembersAsync(request, cancellationToken: cancellationToken);
|
||||
return response.Members.Select(SnPublisherMember.FromProtoValue).ToList();
|
||||
}
|
||||
|
||||
public async Task<string?> SetPublisherFeatureFlag(string publisherId, string flag,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new SetPublisherFeatureFlagRequest
|
||||
{
|
||||
PublisherId = publisherId,
|
||||
Flag = flag
|
||||
};
|
||||
var response = await publishers.SetPublisherFeatureFlagAsync(request, cancellationToken: cancellationToken);
|
||||
return response.Value;
|
||||
}
|
||||
|
||||
public async Task<bool> HasPublisherFeature(string publisherId, string flag,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new HasPublisherFeatureRequest
|
||||
{
|
||||
PublisherId = publisherId,
|
||||
Flag = flag
|
||||
};
|
||||
var response = await publishers.HasPublisherFeatureAsync(request, cancellationToken: cancellationToken);
|
||||
return response.Enabled;
|
||||
}
|
||||
|
||||
public async Task<bool> IsPublisherMember(string publisherId, string accountId,
|
||||
Proto.PublisherMemberRole? role = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var request = new IsPublisherMemberRequest
|
||||
{
|
||||
PublisherId = publisherId,
|
||||
AccountId = accountId,
|
||||
};
|
||||
if (role.HasValue) request.Role = role.Value;
|
||||
var response = await publishers.IsPublisherMemberAsync(request, cancellationToken: cancellationToken);
|
||||
return response.Valid;
|
||||
}
|
||||
|
||||
public async Task<List<SnPublisher>> GetUserPublishers(Guid accountId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await ListPublishers(accountId: accountId.ToString(), realmId: null, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<bool> IsMemberWithRole(Guid publisherId, Guid accountId, Models.PublisherMemberRole role,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var protoRole = role switch
|
||||
{
|
||||
Models.PublisherMemberRole.Owner => Proto.PublisherMemberRole.Owner,
|
||||
Models.PublisherMemberRole.Manager => Proto.PublisherMemberRole.Manager,
|
||||
Models.PublisherMemberRole.Editor => Proto.PublisherMemberRole.Editor,
|
||||
Models.PublisherMemberRole.Viewer => Proto.PublisherMemberRole.Viewer,
|
||||
_ => Proto.PublisherMemberRole.Unspecified
|
||||
};
|
||||
return await IsPublisherMember(publisherId.ToString(), accountId.ToString(), protoRole, cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -116,6 +116,7 @@ public static class ServiceInjectionHelper
|
||||
.ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler()
|
||||
{ ServerCertificateCustomValidationCallback = (_, _, _, _) => true }
|
||||
);
|
||||
services.AddSingleton<RemotePublisherService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
@@ -52,9 +52,6 @@ public class AppDatabase(
|
||||
public DbSet<WebFeed> WebFeeds { get; set; } = null!;
|
||||
public DbSet<WebFeedSubscription> WebFeedSubscriptions { get; set; } = null!;
|
||||
|
||||
public DbSet<SnPublicationSite> PublicationSites { get; set; } = null!;
|
||||
public DbSet<SnPublicationPage> PublicationPages { get; set; } = null!;
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseNpgsql(
|
||||
|
||||
1930
DysonNetwork.Sphere/Migrations/20251119143354_RemovePublicationSites.Designer.cs
generated
Normal file
1930
DysonNetwork.Sphere/Migrations/20251119143354_RemovePublicationSites.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NodaTime;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DysonNetwork.Sphere.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class RemovePublicationSites : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "publication_pages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "publication_sites");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "publication_sites",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
publisher_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
description = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: true),
|
||||
name = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
slug = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_publication_sites", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_publication_sites_publishers_publisher_id",
|
||||
column: x => x.publisher_id,
|
||||
principalTable: "publishers",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "publication_pages",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
site_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
config = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true),
|
||||
path = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: false),
|
||||
preset = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_publication_pages", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_publication_pages_publication_sites_site_id",
|
||||
column: x => x.site_id,
|
||||
principalTable: "publication_sites",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_publication_pages_site_id",
|
||||
table: "publication_pages",
|
||||
column: "site_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_publication_sites_publisher_id",
|
||||
table: "publication_sites",
|
||||
column: "publisher_id");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -881,108 +881,6 @@ namespace DysonNetwork.Sphere.Migrations
|
||||
b.ToTable("post_tags", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationPage", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Dictionary<string, object>>("Config")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasColumnName("config");
|
||||
|
||||
b.Property<Instant>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("created_at");
|
||||
|
||||
b.Property<Instant?>("DeletedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("deleted_at");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8192)
|
||||
.HasColumnType("character varying(8192)")
|
||||
.HasColumnName("path");
|
||||
|
||||
b.Property<string>("Preset")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8192)
|
||||
.HasColumnType("character varying(8192)")
|
||||
.HasColumnName("preset");
|
||||
|
||||
b.Property<Guid>("SiteId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("site_id");
|
||||
|
||||
b.Property<Instant>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("updated_at");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_publication_pages");
|
||||
|
||||
b.HasIndex("SiteId")
|
||||
.HasDatabaseName("ix_publication_pages_site_id");
|
||||
|
||||
b.ToTable("publication_pages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationSite", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("account_id");
|
||||
|
||||
b.Property<Instant>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("created_at");
|
||||
|
||||
b.Property<Instant?>("DeletedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("deleted_at");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(8192)
|
||||
.HasColumnType("character varying(8192)")
|
||||
.HasColumnName("description");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(4096)
|
||||
.HasColumnType("character varying(4096)")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<Guid>("PublisherId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("publisher_id");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasMaxLength(4096)
|
||||
.HasColumnType("character varying(4096)")
|
||||
.HasColumnName("slug");
|
||||
|
||||
b.Property<Instant>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("updated_at");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_publication_sites");
|
||||
|
||||
b.HasIndex("PublisherId")
|
||||
.HasDatabaseName("ix_publication_sites_publisher_id");
|
||||
|
||||
b.ToTable("publication_sites", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublisher", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
@@ -1793,30 +1691,6 @@ namespace DysonNetwork.Sphere.Migrations
|
||||
b.Navigation("Post");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationPage", b =>
|
||||
{
|
||||
b.HasOne("DysonNetwork.Shared.Models.SnPublicationSite", "Site")
|
||||
.WithMany("Pages")
|
||||
.HasForeignKey("SiteId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_publication_pages_publication_sites_site_id");
|
||||
|
||||
b.Navigation("Site");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationSite", b =>
|
||||
{
|
||||
b.HasOne("DysonNetwork.Shared.Models.SnPublisher", "Publisher")
|
||||
.WithMany()
|
||||
.HasForeignKey("PublisherId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_publication_sites_publishers_publisher_id");
|
||||
|
||||
b.Navigation("Publisher");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublisherFeature", b =>
|
||||
{
|
||||
b.HasOne("DysonNetwork.Shared.Models.SnPublisher", "Publisher")
|
||||
@@ -2021,11 +1895,6 @@ namespace DysonNetwork.Sphere.Migrations
|
||||
b.Navigation("Reactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationSite", b =>
|
||||
{
|
||||
b.Navigation("Pages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublisher", b =>
|
||||
{
|
||||
b.Navigation("Collections");
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Shared.Cache;
|
||||
using DysonNetwork.Shared.GeoIp;
|
||||
using DysonNetwork.Shared.Registry;
|
||||
using DysonNetwork.Sphere.Autocompletion;
|
||||
using DysonNetwork.Sphere.Chat;
|
||||
using DysonNetwork.Sphere.Chat.Realtime;
|
||||
@@ -11,7 +10,6 @@ using DysonNetwork.Sphere.Discovery;
|
||||
using DysonNetwork.Sphere.Localization;
|
||||
using DysonNetwork.Sphere.Poll;
|
||||
using DysonNetwork.Sphere.Post;
|
||||
using DysonNetwork.Sphere.Publication;
|
||||
using DysonNetwork.Sphere.Publisher;
|
||||
using DysonNetwork.Sphere.Sticker;
|
||||
using DysonNetwork.Sphere.Timeline;
|
||||
@@ -50,14 +48,6 @@ public static class ServiceCollectionExtensions
|
||||
{
|
||||
options.DataAnnotationLocalizerProvider = (type, factory) =>
|
||||
factory.Create(typeof(SharedResource));
|
||||
})
|
||||
.ConfigureApplicationPartManager(opts =>
|
||||
{
|
||||
var mockingPart = opts.ApplicationParts.FirstOrDefault(a =>
|
||||
a.Name == "DysonNetwork.Pass"
|
||||
);
|
||||
if (mockingPart != null)
|
||||
opts.ApplicationParts.Remove(mockingPart);
|
||||
});
|
||||
services.AddRazorPages();
|
||||
|
||||
@@ -114,7 +104,6 @@ public static class ServiceCollectionExtensions
|
||||
services.AddScoped<DiscoveryService>();
|
||||
services.AddScoped<PollService>();
|
||||
services.AddScoped<AutocompletionService>();
|
||||
services.AddScoped<PublicationSiteService>();
|
||||
|
||||
var translationProvider = configuration["Translation:Provider"]?.ToLower();
|
||||
switch (translationProvider)
|
||||
|
||||
35
DysonNetwork.Zone/.gitignore
vendored
Normal file
35
DysonNetwork.Zone/.gitignore
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# dependencies (bun install)
|
||||
node_modules
|
||||
wwwroot/css/site.dist.css
|
||||
|
||||
# output
|
||||
out
|
||||
dist
|
||||
*.tgz
|
||||
|
||||
# code coverage
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# logs
|
||||
logs
|
||||
_.log
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# caches
|
||||
.eslintcache
|
||||
.cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
51
DysonNetwork.Zone/AppDatabase.cs
Normal file
51
DysonNetwork.Zone/AppDatabase.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using DysonNetwork.Shared.Data;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
|
||||
namespace DysonNetwork.Zone;
|
||||
|
||||
public class AppDatabase(DbContextOptions<AppDatabase> options, IConfiguration configuration) : DbContext(options)
|
||||
{
|
||||
public DbSet<SnPublicationSite> PublicationSites { get; set; } = null!;
|
||||
public DbSet<SnPublicationPage> PublicationPages { get; set; } = null!;
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseNpgsql(
|
||||
configuration.GetConnectionString("App"),
|
||||
opt => opt
|
||||
.ConfigureDataSource(optSource => optSource.EnableDynamicJson())
|
||||
.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)
|
||||
.UseNodaTime()
|
||||
).UseSnakeCaseNamingConvention();
|
||||
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
}
|
||||
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
this.ApplyAuditableAndSoftDelete();
|
||||
return await base.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
base.OnModelCreating(modelBuilder);
|
||||
modelBuilder.ApplySoftDeleteFilters();
|
||||
}
|
||||
}
|
||||
|
||||
public class AppDatabaseFactory : IDesignTimeDbContextFactory<AppDatabase>
|
||||
{
|
||||
public AppDatabase CreateDbContext(string[] args)
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json")
|
||||
.Build();
|
||||
|
||||
var optionsBuilder = new DbContextOptionsBuilder<AppDatabase>();
|
||||
return new AppDatabase(optionsBuilder.Options, configuration);
|
||||
}
|
||||
}
|
||||
32
DysonNetwork.Zone/Dockerfile
Normal file
32
DysonNetwork.Zone/Dockerfile
Normal file
@@ -0,0 +1,32 @@
|
||||
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
|
||||
USER app
|
||||
WORKDIR /app
|
||||
EXPOSE 8080
|
||||
EXPOSE 8081
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
WORKDIR /src
|
||||
COPY ["DysonNetwork.Zone/DysonNetwork.Zone.csproj", "DysonNetwork.Zone/"]
|
||||
COPY ["DysonNetwork.Shared/DysonNetwork.Shared.csproj", "DysonNetwork.Shared/"]
|
||||
COPY ["DysonNetwork.Develop/DysonNetwork.Develop.csproj", "DysonNetwork.Develop/"]
|
||||
RUN dotnet restore "DysonNetwork.Zone/DysonNetwork.Zone.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/DysonNetwork.Zone"
|
||||
RUN apt-get update && apt-get install -y curl && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
|
||||
apt-get install -y nodejs
|
||||
RUN npm install
|
||||
RUN npm run css:build
|
||||
RUN dotnet build "DysonNetwork.Zone.csproj" -c $BUILD_CONFIGURATION -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
ARG BUILD_CONFIGURATION=Release
|
||||
RUN dotnet publish "DysonNetwork.Zone.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "DysonNetwork.Zone.dll"]
|
||||
91
DysonNetwork.Zone/DysonNetwork.Zone.csproj
Normal file
91
DysonNetwork.Zone/DysonNetwork.Zone.csproj
Normal file
@@ -0,0 +1,91 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DysonNetwork.Shared\DysonNetwork.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.11">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NodaTime.Serialization.Protobuf" Version="2.0.2" />
|
||||
<PackageReference Include="NodaTime" Version="3.2.2"/>
|
||||
<PackageReference Include="NodaTime.Serialization.SystemTextJson" Version="1.3.0"/>
|
||||
<PackageReference Include="Grpc.AspNetCore.Server" Version="2.71.0"/>
|
||||
<PackageReference Include="Quartz" Version="3.15.1" />
|
||||
<PackageReference Include="Quartz.AspNetCore" Version="3.15.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\.dockerignore">
|
||||
<Link>.dockerignore</Link>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.rtl.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.rtl.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-utilities.rtl.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.rtl.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.js.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.min.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.min.js.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.esm.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.esm.js.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.esm.min.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.esm.min.js.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.js.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.min.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.min.js.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\LICENSE" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\additional-methods.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\additional-methods.min.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\jquery.validate.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\jquery.validate.min.js" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\LICENSE.md" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\lib\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
148
DysonNetwork.Zone/Migrations/20251119140708_AddPublicationSites.Designer.cs
generated
Normal file
148
DysonNetwork.Zone/Migrations/20251119140708_AddPublicationSites.Designer.cs
generated
Normal file
@@ -0,0 +1,148 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DysonNetwork.Zone;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using NodaTime;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DysonNetwork.Zone.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDatabase))]
|
||||
[Migration("20251119140708_AddPublicationSites")]
|
||||
partial class AddPublicationSites
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.11")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationPage", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Dictionary<string, object>>("Config")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasColumnName("config");
|
||||
|
||||
b.Property<Instant>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("created_at");
|
||||
|
||||
b.Property<Instant?>("DeletedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("deleted_at");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8192)
|
||||
.HasColumnType("character varying(8192)")
|
||||
.HasColumnName("path");
|
||||
|
||||
b.Property<string>("Preset")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8192)
|
||||
.HasColumnType("character varying(8192)")
|
||||
.HasColumnName("preset");
|
||||
|
||||
b.Property<Guid>("SiteId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("site_id");
|
||||
|
||||
b.Property<Instant>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("updated_at");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_publication_pages");
|
||||
|
||||
b.HasIndex("SiteId")
|
||||
.HasDatabaseName("ix_publication_pages_site_id");
|
||||
|
||||
b.ToTable("publication_pages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationSite", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("account_id");
|
||||
|
||||
b.Property<Instant>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("created_at");
|
||||
|
||||
b.Property<Instant?>("DeletedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("deleted_at");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(8192)
|
||||
.HasColumnType("character varying(8192)")
|
||||
.HasColumnName("description");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(4096)
|
||||
.HasColumnType("character varying(4096)")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<Guid>("PublisherId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("publisher_id");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasMaxLength(4096)
|
||||
.HasColumnType("character varying(4096)")
|
||||
.HasColumnName("slug");
|
||||
|
||||
b.Property<Instant>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("updated_at");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_publication_sites");
|
||||
|
||||
b.ToTable("publication_sites", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationPage", b =>
|
||||
{
|
||||
b.HasOne("DysonNetwork.Shared.Models.SnPublicationSite", "Site")
|
||||
.WithMany("Pages")
|
||||
.HasForeignKey("SiteId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_publication_pages_publication_sites_site_id");
|
||||
|
||||
b.Navigation("Site");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationSite", b =>
|
||||
{
|
||||
b.Navigation("Pages");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NodaTime;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DysonNetwork.Zone.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddPublicationSites : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "publication_sites",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
slug = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
name = table.Column<string>(type: "character varying(4096)", maxLength: 4096, nullable: false),
|
||||
description = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: true),
|
||||
publisher_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
account_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_publication_sites", x => x.id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "publication_pages",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
preset = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: false),
|
||||
path = table.Column<string>(type: "character varying(8192)", maxLength: 8192, nullable: false),
|
||||
config = table.Column<Dictionary<string, object>>(type: "jsonb", nullable: false),
|
||||
site_id = table.Column<Guid>(type: "uuid", nullable: false),
|
||||
created_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
updated_at = table.Column<Instant>(type: "timestamp with time zone", nullable: false),
|
||||
deleted_at = table.Column<Instant>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_publication_pages", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "fk_publication_pages_publication_sites_site_id",
|
||||
column: x => x.site_id,
|
||||
principalTable: "publication_sites",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "ix_publication_pages_site_id",
|
||||
table: "publication_pages",
|
||||
column: "site_id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "publication_pages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "publication_sites");
|
||||
}
|
||||
}
|
||||
}
|
||||
145
DysonNetwork.Zone/Migrations/AppDatabaseModelSnapshot.cs
Normal file
145
DysonNetwork.Zone/Migrations/AppDatabaseModelSnapshot.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using DysonNetwork.Zone;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using NodaTime;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace DysonNetwork.Zone.Migrations
|
||||
{
|
||||
[DbContext(typeof(AppDatabase))]
|
||||
partial class AppDatabaseModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.11")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationPage", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Dictionary<string, object>>("Config")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasColumnName("config");
|
||||
|
||||
b.Property<Instant>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("created_at");
|
||||
|
||||
b.Property<Instant?>("DeletedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("deleted_at");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8192)
|
||||
.HasColumnType("character varying(8192)")
|
||||
.HasColumnName("path");
|
||||
|
||||
b.Property<string>("Preset")
|
||||
.IsRequired()
|
||||
.HasMaxLength(8192)
|
||||
.HasColumnType("character varying(8192)")
|
||||
.HasColumnName("preset");
|
||||
|
||||
b.Property<Guid>("SiteId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("site_id");
|
||||
|
||||
b.Property<Instant>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("updated_at");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_publication_pages");
|
||||
|
||||
b.HasIndex("SiteId")
|
||||
.HasDatabaseName("ix_publication_pages_site_id");
|
||||
|
||||
b.ToTable("publication_pages", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationSite", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<Guid>("AccountId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("account_id");
|
||||
|
||||
b.Property<Instant>("CreatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("created_at");
|
||||
|
||||
b.Property<Instant?>("DeletedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("deleted_at");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(8192)
|
||||
.HasColumnType("character varying(8192)")
|
||||
.HasColumnName("description");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(4096)
|
||||
.HasColumnType("character varying(4096)")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<Guid>("PublisherId")
|
||||
.HasColumnType("uuid")
|
||||
.HasColumnName("publisher_id");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasMaxLength(4096)
|
||||
.HasColumnType("character varying(4096)")
|
||||
.HasColumnName("slug");
|
||||
|
||||
b.Property<Instant>("UpdatedAt")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("updated_at");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("pk_publication_sites");
|
||||
|
||||
b.ToTable("publication_sites", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationPage", b =>
|
||||
{
|
||||
b.HasOne("DysonNetwork.Shared.Models.SnPublicationSite", "Site")
|
||||
.WithMany("Pages")
|
||||
.HasForeignKey("SiteId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired()
|
||||
.HasConstraintName("fk_publication_pages_publication_sites_site_id");
|
||||
|
||||
b.Navigation("Site");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DysonNetwork.Shared.Models.SnPublicationSite", b =>
|
||||
{
|
||||
b.Navigation("Pages");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
26
DysonNetwork.Zone/Pages/Error.cshtml
Normal file
26
DysonNetwork.Zone/Pages/Error.cshtml
Normal file
@@ -0,0 +1,26 @@
|
||||
@page
|
||||
@model ErrorModel
|
||||
@{
|
||||
ViewData["Title"] = "Error";
|
||||
}
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
@if (Model.ShowRequestId)
|
||||
{
|
||||
<p>
|
||||
<strong>Request ID:</strong> <code>@Model.RequestId</code>
|
||||
</p>
|
||||
}
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
||||
19
DysonNetwork.Zone/Pages/Error.cshtml.cs
Normal file
19
DysonNetwork.Zone/Pages/Error.cshtml.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace DysonNetwork.Zone.Pages;
|
||||
|
||||
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||
[IgnoreAntiforgeryToken]
|
||||
public class ErrorModel : PageModel
|
||||
{
|
||||
public string? RequestId { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
|
||||
}
|
||||
}
|
||||
12
DysonNetwork.Zone/Pages/Index.cshtml
Normal file
12
DysonNetwork.Zone/Pages/Index.cshtml
Normal file
@@ -0,0 +1,12 @@
|
||||
@page
|
||||
@model IndexModel
|
||||
@{
|
||||
ViewData["Title"] = "Solar Network Pages";
|
||||
}
|
||||
|
||||
<div class="h-screen flex justify-center items-center">
|
||||
<div class="text-center">
|
||||
<h1 class="text-2xl">Hello, World!</h1>
|
||||
<button class="btn btn-primary">Say Ciallo!</button>
|
||||
</div>
|
||||
</div>
|
||||
11
DysonNetwork.Zone/Pages/Index.cshtml.cs
Normal file
11
DysonNetwork.Zone/Pages/Index.cshtml.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace DysonNetwork.Zone.Pages;
|
||||
|
||||
public class IndexModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
{
|
||||
}
|
||||
}
|
||||
8
DysonNetwork.Zone/Pages/Privacy.cshtml
Normal file
8
DysonNetwork.Zone/Pages/Privacy.cshtml
Normal file
@@ -0,0 +1,8 @@
|
||||
@page
|
||||
@model PrivacyModel
|
||||
@{
|
||||
ViewData["Title"] = "Privacy Policy";
|
||||
}
|
||||
<h1>@ViewData["Title"]</h1>
|
||||
|
||||
<p>Use this page to detail your site's privacy policy.</p>
|
||||
11
DysonNetwork.Zone/Pages/Privacy.cshtml.cs
Normal file
11
DysonNetwork.Zone/Pages/Privacy.cshtml.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
|
||||
namespace DysonNetwork.Zone.Pages;
|
||||
|
||||
public class PrivacyModel : PageModel
|
||||
{
|
||||
public void OnGet()
|
||||
{
|
||||
}
|
||||
}
|
||||
20
DysonNetwork.Zone/Pages/Shared/_Layout.cshtml
Normal file
20
DysonNetwork.Zone/Pages/Shared/_Layout.cshtml
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>@ViewData["Title"]</title>
|
||||
<script type="importmap"></script>
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
|
||||
<link rel="stylesheet" href="~/css/site.dist.css" asp-append-version="true"/>
|
||||
<link rel="stylesheet" href="~/DysonNetwork.Zone.styles.css" asp-append-version="true"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@RenderBody()
|
||||
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
|
||||
@await RenderSectionAsync("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
48
DysonNetwork.Zone/Pages/Shared/_Layout.cshtml.css
Normal file
48
DysonNetwork.Zone/Pages/Shared/_Layout.cshtml.css
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
for details on configuring this project to bundle and minify static web assets. */
|
||||
|
||||
a.navbar-brand {
|
||||
white-space: normal;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0077cc;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
.border-top {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
}
|
||||
.border-bottom {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
|
||||
.box-shadow {
|
||||
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
|
||||
}
|
||||
|
||||
button.accept-policy {
|
||||
font-size: 1rem;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
line-height: 60px;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
|
||||
<script src="~/lib/jquery-validation-unobtrusive/dist/jquery.validate.unobtrusive.min.js"></script>
|
||||
3
DysonNetwork.Zone/Pages/_ViewImports.cshtml
Normal file
3
DysonNetwork.Zone/Pages/_ViewImports.cshtml
Normal file
@@ -0,0 +1,3 @@
|
||||
@using DysonNetwork.Zone
|
||||
@namespace DysonNetwork.Zone.Pages
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
3
DysonNetwork.Zone/Pages/_ViewStart.cshtml
Normal file
3
DysonNetwork.Zone/Pages/_ViewStart.cshtml
Normal file
@@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
||||
58
DysonNetwork.Zone/Program.cs
Normal file
58
DysonNetwork.Zone/Program.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using DysonNetwork.Zone;
|
||||
using DysonNetwork.Zone.Startup;
|
||||
using DysonNetwork.Shared.Auth;
|
||||
using DysonNetwork.Shared.Http;
|
||||
using DysonNetwork.Shared.Registry;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.AddServiceDefaults();
|
||||
|
||||
builder.ConfigureAppKestrel(builder.Configuration);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddControllers();
|
||||
|
||||
builder.Services.AddAppServices();
|
||||
builder.Services.AddAppAuthentication();
|
||||
builder.Services.AddAppFlushHandlers();
|
||||
builder.Services.AddAppBusinessServices(builder.Configuration);
|
||||
builder.Services.AddAppScheduledJobs();
|
||||
|
||||
builder.Services.AddDysonAuth();
|
||||
builder.Services.AddRingService();
|
||||
builder.Services.AddAccountService();
|
||||
builder.Services.AddSphereService();
|
||||
|
||||
builder.AddSwaggerManifest(
|
||||
"DysonNetwork.Zone",
|
||||
"The zone service in the Solar Network."
|
||||
);
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.MapDefaultEndpoints();
|
||||
|
||||
// Run database migrations
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDatabase>();
|
||||
await db.Database.MigrateAsync();
|
||||
}
|
||||
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (!app.Environment.IsDevelopment())
|
||||
app.UseExceptionHandler("/Error");
|
||||
|
||||
app.ConfigureAppMiddleware(builder.Configuration);
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseRouting();
|
||||
app.MapRazorPages();
|
||||
|
||||
app.UseSwaggerManifest("DysonNetwork.Zone");
|
||||
|
||||
app.Run();
|
||||
21
DysonNetwork.Zone/Properties/launchSettings.json
Normal file
21
DysonNetwork.Zone/Properties/launchSettings.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Sphere.Publisher;
|
||||
using DysonNetwork.Shared.Registry;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PublicationPagePresets = DysonNetwork.Shared.Models.PublicationPagePresets;
|
||||
|
||||
namespace DysonNetwork.Sphere.Publication;
|
||||
namespace DysonNetwork.Zone.Publication;
|
||||
|
||||
[ApiController]
|
||||
[Route("/api/sites")]
|
||||
public class PublicationSiteController(
|
||||
PublicationSiteService publicationService,
|
||||
PublisherService publisherService
|
||||
RemotePublisherService publisherService
|
||||
) : ControllerBase
|
||||
{
|
||||
[HttpGet("{slug}")]
|
||||
@@ -2,14 +2,13 @@ using System.Text.RegularExpressions;
|
||||
using DysonNetwork.Shared.Auth;
|
||||
using DysonNetwork.Shared.Models;
|
||||
using DysonNetwork.Shared.Registry;
|
||||
using DysonNetwork.Sphere.Publisher;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DysonNetwork.Sphere.Publication;
|
||||
namespace DysonNetwork.Zone.Publication;
|
||||
|
||||
public class PublicationSiteService(
|
||||
AppDatabase db,
|
||||
PublisherService publisherService,
|
||||
RemotePublisherService publisherService,
|
||||
RemoteAccountService remoteAccounts
|
||||
)
|
||||
{
|
||||
26
DysonNetwork.Zone/Startup/ApplicationConfiguration.cs
Normal file
26
DysonNetwork.Zone/Startup/ApplicationConfiguration.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using DysonNetwork.Shared.Auth;
|
||||
using DysonNetwork.Shared.Http;
|
||||
|
||||
namespace DysonNetwork.Zone.Startup;
|
||||
|
||||
public static class ApplicationConfiguration
|
||||
{
|
||||
public static WebApplication ConfigureAppMiddleware(this WebApplication app, IConfiguration configuration)
|
||||
{
|
||||
app.UseRequestLocalization();
|
||||
|
||||
app.ConfigureForwardedHeaders(configuration);
|
||||
|
||||
app.UseWebSockets();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
app.UseMiddleware<PermissionMiddleware>();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
// Map gRPC services
|
||||
app.MapGrpcReflectionService();
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
61
DysonNetwork.Zone/Startup/BroadcastEventHandler.cs
Normal file
61
DysonNetwork.Zone/Startup/BroadcastEventHandler.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
using DysonNetwork.Shared.Stream;
|
||||
using NATS.Client.Core;
|
||||
using NATS.Client.JetStream.Models;
|
||||
using NATS.Net;
|
||||
|
||||
namespace DysonNetwork.Zone.Startup;
|
||||
|
||||
public class BroadcastEventHandler(
|
||||
IServiceProvider serviceProvider,
|
||||
ILogger<BroadcastEventHandler> logger,
|
||||
INatsConnection nats,
|
||||
RingService.RingServiceClient pusher
|
||||
) : BackgroundService
|
||||
{
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
var accountTask = HandleAccountDeletions(stoppingToken);
|
||||
|
||||
await Task.WhenAll(accountTask);
|
||||
}
|
||||
|
||||
private async Task HandleAccountDeletions(CancellationToken stoppingToken)
|
||||
{
|
||||
var js = nats.CreateJetStreamContext();
|
||||
|
||||
await js.EnsureStreamCreated("account_events", [AccountDeletedEvent.Type]);
|
||||
|
||||
var consumer = await js.CreateOrUpdateConsumerAsync("account_events",
|
||||
new ConsumerConfig("sphere_account_deleted_handler"), cancellationToken: stoppingToken);
|
||||
|
||||
await foreach (var msg in consumer.ConsumeAsync<byte[]>(cancellationToken: stoppingToken))
|
||||
{
|
||||
try
|
||||
{
|
||||
var evt = JsonSerializer.Deserialize<AccountDeletedEvent>(msg.Data, GrpcTypeHelper.SerializerOptions);
|
||||
if (evt == null)
|
||||
{
|
||||
await msg.AckAsync(cancellationToken: stoppingToken);
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.LogInformation("Account deleted: {AccountId}", evt.AccountId);
|
||||
|
||||
using var scope = serviceProvider.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDatabase>();
|
||||
|
||||
// TODO clean up data
|
||||
|
||||
await msg.AckAsync(cancellationToken: stoppingToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "Error processing AccountDeleted");
|
||||
await msg.NakAsync(cancellationToken: stoppingToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
17
DysonNetwork.Zone/Startup/ScheduledJobsConfiguration.cs
Normal file
17
DysonNetwork.Zone/Startup/ScheduledJobsConfiguration.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Quartz;
|
||||
|
||||
namespace DysonNetwork.Zone.Startup;
|
||||
|
||||
public static class ScheduledJobsConfiguration
|
||||
{
|
||||
public static IServiceCollection AddAppScheduledJobs(this IServiceCollection services)
|
||||
{
|
||||
services.AddQuartz(q =>
|
||||
{
|
||||
|
||||
});
|
||||
services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
82
DysonNetwork.Zone/Startup/ServiceCollectionExtensions.cs
Normal file
82
DysonNetwork.Zone/Startup/ServiceCollectionExtensions.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System.Globalization;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Shared.Cache;
|
||||
using DysonNetwork.Shared.GeoIp;
|
||||
using DysonNetwork.Zone.Publication;
|
||||
using NodaTime;
|
||||
using NodaTime.Serialization.SystemTextJson;
|
||||
|
||||
namespace DysonNetwork.Zone.Startup;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddAppServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddLocalization(options => options.ResourcesPath = "Resources");
|
||||
|
||||
services.AddDbContext<AppDatabase>();
|
||||
services.AddSingleton<IClock>(SystemClock.Instance);
|
||||
services.AddHttpContextAccessor();
|
||||
services.AddSingleton<ICacheService, CacheServiceRedis>();
|
||||
|
||||
services.AddHttpClient();
|
||||
|
||||
services
|
||||
.AddControllers()
|
||||
.AddJsonOptions(options =>
|
||||
{
|
||||
options.JsonSerializerOptions.NumberHandling =
|
||||
JsonNumberHandling.AllowNamedFloatingPointLiterals;
|
||||
options.JsonSerializerOptions.PropertyNamingPolicy =
|
||||
JsonNamingPolicy.SnakeCaseLower;
|
||||
|
||||
options.JsonSerializerOptions.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
|
||||
});
|
||||
services.AddRazorPages();
|
||||
|
||||
services.AddGrpc(options =>
|
||||
{
|
||||
options.EnableDetailedErrors = true;
|
||||
});
|
||||
services.AddGrpcReflection();
|
||||
|
||||
services.Configure<RequestLocalizationOptions>(options =>
|
||||
{
|
||||
var supportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("zh-Hans") };
|
||||
|
||||
options.SupportedCultures = supportedCultures;
|
||||
options.SupportedUICultures = supportedCultures;
|
||||
});
|
||||
|
||||
services.AddHostedService<BroadcastEventHandler>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddAppAuthentication(this IServiceCollection services)
|
||||
{
|
||||
services.AddAuthorization();
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddAppFlushHandlers(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<FlushBufferService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddAppBusinessServices(
|
||||
this IServiceCollection services,
|
||||
IConfiguration configuration
|
||||
)
|
||||
{
|
||||
services.Configure<GeoIpOptions>(configuration.GetSection("GeoIP"));
|
||||
services.AddScoped<GeoIpService>();
|
||||
|
||||
services.AddScoped<PublicationSiteService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
17
DysonNetwork.Zone/appsettings.json
Normal file
17
DysonNetwork.Zone/appsettings.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"DetailedErrors": true,
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"App": "Host=localhost;Port=5432;Database=dyson_zone;Username=postgres;Password=postgres;Include Error Detail=True;Maximum Pool Size=20;Connection Idle Lifetime=60"
|
||||
},
|
||||
"KnownProxies": ["127.0.0.1", "::1"],
|
||||
"Swagger": {
|
||||
"PublicBasePath": "/zone"
|
||||
}
|
||||
}
|
||||
179
DysonNetwork.Zone/bun.lock
Normal file
179
DysonNetwork.Zone/bun.lock
Normal file
@@ -0,0 +1,179 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "dyson-zone",
|
||||
"devDependencies": {
|
||||
"@tailwindcss/cli": "^4.1.17",
|
||||
"@types/bun": "latest",
|
||||
"daisyui": "^5.5.5",
|
||||
"tailwindcss": "^4.1.17",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
|
||||
|
||||
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
|
||||
|
||||
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||
|
||||
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
|
||||
|
||||
"@parcel/watcher": ["@parcel/watcher@2.5.1", "", { "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^7.0.0" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-freebsd-x64": "2.5.1", "@parcel/watcher-linux-arm-glibc": "2.5.1", "@parcel/watcher-linux-arm-musl": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-ia32": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1" } }, "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg=="],
|
||||
|
||||
"@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.1", "", { "os": "android", "cpu": "arm64" }, "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA=="],
|
||||
|
||||
"@parcel/watcher-darwin-arm64": ["@parcel/watcher-darwin-arm64@2.5.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw=="],
|
||||
|
||||
"@parcel/watcher-darwin-x64": ["@parcel/watcher-darwin-x64@2.5.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg=="],
|
||||
|
||||
"@parcel/watcher-freebsd-x64": ["@parcel/watcher-freebsd-x64@2.5.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ=="],
|
||||
|
||||
"@parcel/watcher-linux-arm-glibc": ["@parcel/watcher-linux-arm-glibc@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA=="],
|
||||
|
||||
"@parcel/watcher-linux-arm-musl": ["@parcel/watcher-linux-arm-musl@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q=="],
|
||||
|
||||
"@parcel/watcher-linux-arm64-glibc": ["@parcel/watcher-linux-arm64-glibc@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w=="],
|
||||
|
||||
"@parcel/watcher-linux-arm64-musl": ["@parcel/watcher-linux-arm64-musl@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg=="],
|
||||
|
||||
"@parcel/watcher-linux-x64-glibc": ["@parcel/watcher-linux-x64-glibc@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A=="],
|
||||
|
||||
"@parcel/watcher-linux-x64-musl": ["@parcel/watcher-linux-x64-musl@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg=="],
|
||||
|
||||
"@parcel/watcher-win32-arm64": ["@parcel/watcher-win32-arm64@2.5.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw=="],
|
||||
|
||||
"@parcel/watcher-win32-ia32": ["@parcel/watcher-win32-ia32@2.5.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ=="],
|
||||
|
||||
"@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
|
||||
|
||||
"@tailwindcss/cli": ["@tailwindcss/cli@4.1.17", "", { "dependencies": { "@parcel/watcher": "^2.5.1", "@tailwindcss/node": "4.1.17", "@tailwindcss/oxide": "4.1.17", "enhanced-resolve": "^5.18.3", "mri": "^1.2.0", "picocolors": "^1.1.1", "tailwindcss": "4.1.17" }, "bin": { "tailwindcss": "dist/index.mjs" } }, "sha512-jUIxcyUNlCC2aNPnyPEWU/L2/ik3pB4fF3auKGXr8AvN3T3OFESVctFKOBoPZQaZJIeUpPn1uCLp0MRxuek8gg=="],
|
||||
|
||||
"@tailwindcss/node": ["@tailwindcss/node@4.1.17", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.17" } }, "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg=="],
|
||||
|
||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.17", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.17", "@tailwindcss/oxide-darwin-arm64": "4.1.17", "@tailwindcss/oxide-darwin-x64": "4.1.17", "@tailwindcss/oxide-freebsd-x64": "4.1.17", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", "@tailwindcss/oxide-linux-x64-musl": "4.1.17", "@tailwindcss/oxide-wasm32-wasi": "4.1.17", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA=="],
|
||||
|
||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.17", "", { "os": "android", "cpu": "arm64" }, "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.17", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.17", "", { "os": "darwin", "cpu": "x64" }, "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog=="],
|
||||
|
||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.17", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17", "", { "os": "linux", "cpu": "arm" }, "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.17", "", { "dependencies": { "@emnapi/core": "^1.6.0", "@emnapi/runtime": "^1.6.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.17", "", { "os": "win32", "cpu": "arm64" }, "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.17", "", { "os": "win32", "cpu": "x64" }, "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.3.2", "", { "dependencies": { "bun-types": "1.3.2" } }, "sha512-t15P7k5UIgHKkxwnMNkJbWlh/617rkDGEdSsDbu+qNHTaz9SKf7aC8fiIlUdD5RPpH6GEkP0cK7WlvmrEBRtWg=="],
|
||||
|
||||
"@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.6", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w=="],
|
||||
|
||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||
|
||||
"bun-types": ["bun-types@1.3.2", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-i/Gln4tbzKNuxP70OWhJRZz1MRfvqExowP7U6JKoI8cntFrtxg7RJK3jvz7wQW54UuvNC8tbKHHri5fy74FVqg=="],
|
||||
|
||||
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||
|
||||
"daisyui": ["daisyui@5.5.5", "", {}, "sha512-ekvI93ZkWIJoCOtDl0D2QMxnWvTejk9V5nWBqRv+7t0xjiBXqAK5U6o6JE2RPvlIC3EqwNyUoIZSdHX9MZK3nw=="],
|
||||
|
||||
"detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
|
||||
|
||||
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
|
||||
|
||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||
|
||||
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||
|
||||
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
||||
|
||||
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
||||
|
||||
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
||||
|
||||
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
|
||||
|
||||
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
|
||||
|
||||
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
|
||||
|
||||
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
|
||||
|
||||
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
|
||||
|
||||
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
|
||||
|
||||
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
|
||||
|
||||
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
|
||||
|
||||
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
|
||||
|
||||
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
|
||||
|
||||
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
|
||||
|
||||
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
|
||||
|
||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||
|
||||
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
||||
|
||||
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
|
||||
|
||||
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
|
||||
|
||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||
|
||||
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"tailwindcss": ["tailwindcss@4.1.17", "", {}, "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q=="],
|
||||
|
||||
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
|
||||
|
||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||
|
||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.7", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||
|
||||
"lightningcss/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||
}
|
||||
}
|
||||
18
DysonNetwork.Zone/package.json
Normal file
18
DysonNetwork.Zone/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "dyson-zone",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"@tailwindcss/cli": "^4.1.17",
|
||||
"@types/bun": "latest",
|
||||
"daisyui": "^5.5.5",
|
||||
"tailwindcss": "^4.1.17"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"css:build": "npx @tailwindcss/cli -i ./wwwroot/css/site.css -o ./wwwroot/css/site.dist.css"
|
||||
}
|
||||
}
|
||||
29
DysonNetwork.Zone/tsconfig.json
Normal file
29
DysonNetwork.Zone/tsconfig.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Environment setup & latest features
|
||||
"lib": ["ESNext"],
|
||||
"target": "ESNext",
|
||||
"module": "Preserve",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noImplicitOverride": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
}
|
||||
}
|
||||
8
DysonNetwork.Zone/wwwroot/css/site.css
Normal file
8
DysonNetwork.Zone/wwwroot/css/site.css
Normal file
@@ -0,0 +1,8 @@
|
||||
@import "tailwindcss";
|
||||
@plugin "daisyui";
|
||||
|
||||
@layer theme, base, components, utilities;
|
||||
|
||||
@import "tailwindcss/theme.css" layer(theme);
|
||||
@import "tailwindcss/preflight.css" layer(base);
|
||||
@import "tailwindcss/utilities.css" layer(utilities);
|
||||
BIN
DysonNetwork.Zone/wwwroot/favicon.ico
Normal file
BIN
DysonNetwork.Zone/wwwroot/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
4
DysonNetwork.Zone/wwwroot/js/site.js
Normal file
4
DysonNetwork.Zone/wwwroot/js/site.js
Normal file
@@ -0,0 +1,4 @@
|
||||
// Please see documentation at https://learn.microsoft.com/aspnet/core/client-side/bundling-and-minification
|
||||
// for details on configuring this project to bundle and minify static web assets.
|
||||
|
||||
// Write your JavaScript code.
|
||||
@@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Gateway", "Dys
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Insight", "DysonNetwork.Insight\DysonNetwork.Insight.csproj", "{E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Zone", "DysonNetwork.Zone\DysonNetwork.Zone.csproj", "{E255B723-CAC9-4AC8-AA3B-116CC256E63C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -141,6 +143,18 @@ Global
|
||||
{E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E255B723-CAC9-4AC8-AA3B-116CC256E63C}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in New Issue
Block a user