Add static type reference model generation to all apps to prevent using magic strings (#1404)
This commit is contained in:
+67
@@ -0,0 +1,67 @@
|
||||
// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
package net.aliasvault.app.vaultstore.models
|
||||
|
||||
/**
|
||||
* Field types for rendering and validation.
|
||||
*/
|
||||
object FieldType {
|
||||
/**
|
||||
* Text field type.
|
||||
*/
|
||||
const val TEXT = "Text"
|
||||
|
||||
/**
|
||||
* Password field type.
|
||||
*/
|
||||
const val PASSWORD = "Password"
|
||||
|
||||
/**
|
||||
* Hidden field type.
|
||||
*/
|
||||
const val HIDDEN = "Hidden"
|
||||
|
||||
/**
|
||||
* Email field type.
|
||||
*/
|
||||
const val EMAIL = "Email"
|
||||
|
||||
/**
|
||||
* URL field type.
|
||||
*/
|
||||
const val U_R_L = "URL"
|
||||
|
||||
/**
|
||||
* Date field type.
|
||||
*/
|
||||
const val DATE = "Date"
|
||||
|
||||
/**
|
||||
* Number field type.
|
||||
*/
|
||||
const val NUMBER = "Number"
|
||||
|
||||
/**
|
||||
* Phone field type.
|
||||
*/
|
||||
const val PHONE = "Phone"
|
||||
|
||||
/**
|
||||
* TextArea field type.
|
||||
*/
|
||||
const val TEXT_AREA = "TextArea"
|
||||
|
||||
/**
|
||||
* All available field types.
|
||||
*/
|
||||
val all = listOf(TEXT, PASSWORD, HIDDEN, EMAIL, U_R_L, DATE, NUMBER, PHONE, TEXT_AREA)
|
||||
|
||||
/**
|
||||
* Checks if a string value is a valid field type.
|
||||
*/
|
||||
fun isValid(value: String?): Boolean {
|
||||
return value in all
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
package net.aliasvault.app.vaultstore.models
|
||||
|
||||
/**
|
||||
* Item types supported by the vault.
|
||||
*/
|
||||
object ItemType {
|
||||
/**
|
||||
* Login item type.
|
||||
*/
|
||||
const val LOGIN = "Login"
|
||||
|
||||
/**
|
||||
* Alias item type.
|
||||
*/
|
||||
const val ALIAS = "Alias"
|
||||
|
||||
/**
|
||||
* CreditCard item type.
|
||||
*/
|
||||
const val CREDIT_CARD = "CreditCard"
|
||||
|
||||
/**
|
||||
* Note item type.
|
||||
*/
|
||||
const val NOTE = "Note"
|
||||
|
||||
/**
|
||||
* All available item types.
|
||||
*/
|
||||
val all = listOf(LOGIN, ALIAS, CREDIT_CARD, NOTE)
|
||||
|
||||
/**
|
||||
* Checks if a string value is a valid item type.
|
||||
*/
|
||||
fun isValid(value: String?): Boolean {
|
||||
return value in all
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Field types for rendering and validation.
|
||||
public struct FieldType {
|
||||
/// Text field type.
|
||||
public static let text = "Text"
|
||||
|
||||
/// Password field type.
|
||||
public static let password = "Password"
|
||||
|
||||
/// Hidden field type.
|
||||
public static let hidden = "Hidden"
|
||||
|
||||
/// Email field type.
|
||||
public static let email = "Email"
|
||||
|
||||
/// URL field type.
|
||||
public static let uRL = "URL"
|
||||
|
||||
/// Date field type.
|
||||
public static let date = "Date"
|
||||
|
||||
/// Number field type.
|
||||
public static let number = "Number"
|
||||
|
||||
/// Phone field type.
|
||||
public static let phone = "Phone"
|
||||
|
||||
/// TextArea field type.
|
||||
public static let textArea = "TextArea"
|
||||
|
||||
/// All available field types.
|
||||
public static let all = [text, password, hidden, email, uRL, date, number, phone, textArea]
|
||||
|
||||
/// Checks if a string value is a valid field type.
|
||||
public static func isValid(_ value: String?) -> Bool {
|
||||
guard let value = value else { return false }
|
||||
return all.contains(value)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Item types supported by the vault.
|
||||
public struct ItemType {
|
||||
/// Login item type.
|
||||
public static let login = "Login"
|
||||
|
||||
/// Alias item type.
|
||||
public static let alias = "Alias"
|
||||
|
||||
/// CreditCard item type.
|
||||
public static let creditCard = "CreditCard"
|
||||
|
||||
/// Note item type.
|
||||
public static let note = "Note"
|
||||
|
||||
/// All available item types.
|
||||
public static let all = [login, alias, creditCard, note]
|
||||
|
||||
/// Checks if a string value is a valid item type.
|
||||
public static func isValid(_ value: String?) -> Bool {
|
||||
guard let value = value else { return false }
|
||||
return all.contains(value)
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@
|
||||
@* FieldBlock component - renders a single field based on its type *@
|
||||
@switch (Field.FieldType)
|
||||
{
|
||||
case "Password":
|
||||
case "Hidden":
|
||||
case FieldType.Password:
|
||||
case FieldType.Hidden:
|
||||
<div class="col-span-6">
|
||||
<CopyPastePasswordFormRow
|
||||
Id="@GetFieldId()"
|
||||
@@ -14,7 +14,7 @@
|
||||
Value="@(Field.Value ?? string.Empty)" />
|
||||
</div>
|
||||
break;
|
||||
case "TextArea":
|
||||
case FieldType.TextArea:
|
||||
<div class="col-span-6">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">@GetLabel()</label>
|
||||
<div class="p-3 bg-gray-50 dark:bg-gray-700 rounded-lg text-gray-900 dark:text-white whitespace-pre-wrap text-sm">
|
||||
@@ -22,7 +22,7 @@
|
||||
</div>
|
||||
</div>
|
||||
break;
|
||||
case "URL":
|
||||
case FieldType.URL:
|
||||
<div class="col-span-6">
|
||||
<label class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">@GetLabel()</label>
|
||||
@if (!string.IsNullOrEmpty(Field.Value))
|
||||
@@ -40,7 +40,7 @@
|
||||
}
|
||||
</div>
|
||||
break;
|
||||
case "Date":
|
||||
case FieldType.Date:
|
||||
<div class="@(FullWidth ? "col-span-6" : "col-span-6 sm:col-span-3")">
|
||||
<CopyPasteFormRow
|
||||
Id="@GetFieldId()"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@using AliasVault.Client.Main.Models
|
||||
@using AliasClientDb.Models
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@* ItemCard component - displays an item in a card format with appropriate icon and information *@
|
||||
@@ -67,7 +68,7 @@
|
||||
/// </summary>
|
||||
private string GetDisplayText()
|
||||
{
|
||||
if (Obj.ItemType == ItemTypes.CreditCard)
|
||||
if (Obj.ItemType == ItemType.CreditCard)
|
||||
{
|
||||
// For credit cards, show masked card number if available
|
||||
if (!string.IsNullOrEmpty(Obj.CardNumber) && Obj.CardNumber.Length >= 4)
|
||||
@@ -78,7 +79,7 @@
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (Obj.ItemType == ItemTypes.Note)
|
||||
if (Obj.ItemType == ItemType.Note)
|
||||
{
|
||||
// For notes, no secondary text needed
|
||||
return string.Empty;
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
@using AliasVault.Client.Main.Models
|
||||
@using AliasClientDb.Models
|
||||
@using AliasVault.Client.Main.Utilities
|
||||
@using ItemTypeClass = AliasClientDb.Models.ItemType
|
||||
|
||||
@* ItemIcon component - displays contextually appropriate icons based on item type *@
|
||||
@* For Login/Alias: Uses the Logo field if available, falls back to key placeholder *@
|
||||
@* For CreditCard: Shows card brand icons (Visa, MC, Amex, Discover) based on card number *@
|
||||
@* For Note: Shows a document/note icon *@
|
||||
|
||||
@if (ItemType == ItemTypes.Note)
|
||||
@if (ItemType == ItemTypeClass.Note)
|
||||
{
|
||||
@* Note icon - document style *@
|
||||
<svg class="@SizeClass flex-shrink-0" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -17,7 +19,7 @@
|
||||
<rect x="10" y="22" width="8" height="1.5" rx="0.75" fill="#ffe096"/>
|
||||
</svg>
|
||||
}
|
||||
else if (ItemType == ItemTypes.CreditCard)
|
||||
else if (ItemType == ItemTypeClass.CreditCard)
|
||||
{
|
||||
@* Credit card icon - detect brand and show appropriate icon *@
|
||||
@switch (CardBrandDetector.Detect(CardNumber))
|
||||
@@ -92,7 +94,7 @@ else
|
||||
/// Gets or sets the item type (Login, Alias, CreditCard, Note).
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string ItemType { get; set; } = ItemTypes.Login;
|
||||
public string ItemType { get; set; } = ItemTypeClass.Login;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the logo bytes for Login/Alias items.
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
@using AliasVault.Client.Main.Models
|
||||
@using AliasClientDb.Models
|
||||
@using ItemTypeClass = AliasClientDb.Models.ItemType
|
||||
@using Microsoft.Extensions.Localization
|
||||
|
||||
@inject IStringLocalizerFactory LocalizerFactory
|
||||
@@ -22,7 +24,7 @@
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
@if (SelectedType == ItemTypes.Alias && !IsEditMode && OnRegenerateAlias.HasDelegate)
|
||||
@if (SelectedType == ItemType.Alias && !IsEditMode && OnRegenerateAlias.HasDelegate)
|
||||
{
|
||||
<button type="button"
|
||||
@onclick="HandleRegenerate"
|
||||
@@ -41,7 +43,7 @@
|
||||
{
|
||||
<div class="fixed inset-0 z-10" @onclick="CloseDropdown"></div>
|
||||
<div class="absolute z-20 mt-1 w-full bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg overflow-hidden">
|
||||
@foreach (var itemType in ItemTypes.All)
|
||||
@foreach (var itemType in ItemType.All)
|
||||
{
|
||||
<button type="button"
|
||||
@onclick="() => SelectType(itemType)"
|
||||
@@ -72,7 +74,7 @@
|
||||
/// The currently selected item type.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string SelectedType { get; set; } = ItemTypes.Login;
|
||||
public string SelectedType { get; set; } = ItemTypeClass.Login;
|
||||
|
||||
/// <summary>
|
||||
/// Callback when item type changes.
|
||||
@@ -135,10 +137,10 @@
|
||||
{
|
||||
return itemType switch
|
||||
{
|
||||
ItemTypes.Login => Localizer["TypeLogin"],
|
||||
ItemTypes.Alias => Localizer["TypeAlias"],
|
||||
ItemTypes.CreditCard => Localizer["TypeCreditCard"],
|
||||
ItemTypes.Note => Localizer["TypeNote"],
|
||||
ItemType.Login => Localizer["TypeLogin"],
|
||||
ItemType.Alias => Localizer["TypeAlias"],
|
||||
ItemType.CreditCard => Localizer["TypeCreditCard"],
|
||||
ItemType.Note => Localizer["TypeNote"],
|
||||
_ => itemType
|
||||
};
|
||||
}
|
||||
@@ -147,10 +149,10 @@
|
||||
{
|
||||
var svg = itemType switch
|
||||
{
|
||||
ItemTypes.Login => """<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" /></svg>""",
|
||||
ItemTypes.Alias => """<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>""",
|
||||
ItemTypes.CreditCard => """<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" /></svg>""",
|
||||
ItemTypes.Note => """<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>""",
|
||||
ItemType.Login => """<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" /></svg>""",
|
||||
ItemType.Alias => """<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>""",
|
||||
ItemType.CreditCard => """<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" /></svg>""",
|
||||
ItemType.Note => """<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>""",
|
||||
_ => """<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>"""
|
||||
};
|
||||
return new MarkupString(svg);
|
||||
|
||||
+25
-24
@@ -10,6 +10,7 @@
|
||||
@implements IAsyncDisposable
|
||||
@using AliasClientDb
|
||||
@using AliasClientDb.Models
|
||||
@using ItemTypeClass = AliasClientDb.Models.ItemType
|
||||
|
||||
<button @ref="buttonRef" @onclick="TogglePopup" id="quickIdentityButton" class="px-4 py-2 text-sm font-medium text-white bg-gradient-to-r from-primary-500 to-primary-600 hover:from-primary-600 hover:to-primary-700 focus:outline-none dark:from-primary-400 dark:to-primary-500 dark:hover:from-primary-500 dark:hover:to-primary-600 rounded-md shadow-sm transition duration-150 ease-in-out transform hover:scale-105 active:scale-95 focus:shadow-outline">
|
||||
@Localizer["NewAliasButtonShort"] <span class="hidden md:inline">@Localizer["NewAliasButtonText"].Value.Substring(1).Trim()</span>
|
||||
@@ -23,7 +24,7 @@
|
||||
@* Item Type Selector *@
|
||||
<div class="mb-4">
|
||||
<div class="flex gap-1">
|
||||
@foreach (var itemType in ItemTypes.All)
|
||||
@foreach (var itemType in ItemType.All)
|
||||
{
|
||||
<button type="button"
|
||||
@onclick="() => SelectItemType(itemType)"
|
||||
@@ -43,7 +44,7 @@
|
||||
<EditFormRow Id="serviceName" Label="@Localizer["NameLabel"]" Placeholder="@GetNamePlaceholder()" @bind-Value="Model.ServiceName"></EditFormRow>
|
||||
<ValidationMessage For="() => Model.ServiceName"/>
|
||||
</div>
|
||||
@if (Model.ItemType == ItemTypes.Login || Model.ItemType == ItemTypes.Alias)
|
||||
@if (Model.ItemType == ItemType.Login || Model.ItemType == ItemType.Alias)
|
||||
{
|
||||
<div class="mb-4">
|
||||
<EditFormRow Id="serviceUrl" Label="@Localizer["WebsiteUrlLabel"]" OnFocus="OnFocusUrlInput" @bind-Value="Model.ServiceUrl"></EditFormRow>
|
||||
@@ -52,7 +53,7 @@
|
||||
}
|
||||
<div class="flex justify-between items-center">
|
||||
<button id="quickIdentitySubmit" type="submit" class="@GetSubmitButtonClasses() text-white font-bold py-2 px-4 rounded flex items-center gap-2">
|
||||
@if (Model.ItemType == ItemTypes.Alias)
|
||||
@if (Model.ItemType == ItemType.Alias)
|
||||
{
|
||||
@Localizer["CreateButton"]
|
||||
}
|
||||
@@ -149,7 +150,7 @@
|
||||
|
||||
// Clear the input fields and default to Alias type
|
||||
Model = new();
|
||||
Model.ItemType = ItemTypes.Alias;
|
||||
Model.ItemType = ItemType.Alias;
|
||||
Model.ServiceUrl = ItemService.DefaultServiceUrl;
|
||||
|
||||
await UpdatePopupStyle();
|
||||
@@ -194,7 +195,7 @@
|
||||
/// </summary>
|
||||
private async Task HandleFormSubmit()
|
||||
{
|
||||
if (Model.ItemType == ItemTypes.Alias)
|
||||
if (Model.ItemType == ItemType.Alias)
|
||||
{
|
||||
await CreateAlias();
|
||||
}
|
||||
@@ -221,7 +222,7 @@
|
||||
var item = new Item
|
||||
{
|
||||
Name = Model.ServiceName,
|
||||
ItemType = ItemTypes.Alias,
|
||||
ItemType = ItemType.Alias,
|
||||
FieldValues = new List<FieldValue>()
|
||||
};
|
||||
|
||||
@@ -279,10 +280,10 @@
|
||||
{
|
||||
return Model.ItemType switch
|
||||
{
|
||||
ItemTypes.Alias => Localizer["CreateNewAliasTitle"],
|
||||
ItemTypes.Login => Localizer["CreateNewLoginTitle"],
|
||||
ItemTypes.CreditCard => Localizer["CreateNewCreditCardTitle"],
|
||||
ItemTypes.Note => Localizer["CreateNewNoteTitle"],
|
||||
ItemType.Alias => Localizer["CreateNewAliasTitle"],
|
||||
ItemType.Login => Localizer["CreateNewLoginTitle"],
|
||||
ItemType.CreditCard => Localizer["CreateNewCreditCardTitle"],
|
||||
ItemType.Note => Localizer["CreateNewNoteTitle"],
|
||||
_ => Localizer["CreateNewAliasTitle"]
|
||||
};
|
||||
}
|
||||
@@ -294,10 +295,10 @@
|
||||
{
|
||||
return Model.ItemType switch
|
||||
{
|
||||
ItemTypes.Login => Localizer["NamePlaceholderLogin"],
|
||||
ItemTypes.Alias => Localizer["NamePlaceholderAlias"],
|
||||
ItemTypes.CreditCard => Localizer["NamePlaceholderCard"],
|
||||
ItemTypes.Note => Localizer["NamePlaceholderNote"],
|
||||
ItemType.Login => Localizer["NamePlaceholderLogin"],
|
||||
ItemType.Alias => Localizer["NamePlaceholderAlias"],
|
||||
ItemType.CreditCard => Localizer["NamePlaceholderCard"],
|
||||
ItemType.Note => Localizer["NamePlaceholderNote"],
|
||||
_ => Localizer["NamePlaceholderLogin"]
|
||||
};
|
||||
}
|
||||
@@ -307,7 +308,7 @@
|
||||
/// </summary>
|
||||
private string GetSubmitButtonClasses()
|
||||
{
|
||||
return Model.ItemType == ItemTypes.Alias
|
||||
return Model.ItemType == ItemType.Alias
|
||||
? "bg-green-600 hover:bg-green-700"
|
||||
: "bg-primary-600 hover:bg-primary-700";
|
||||
}
|
||||
@@ -319,10 +320,10 @@
|
||||
{
|
||||
return itemType switch
|
||||
{
|
||||
ItemTypes.Login => Localizer["TypeLogin"],
|
||||
ItemTypes.Alias => Localizer["TypeAlias"],
|
||||
ItemTypes.CreditCard => Localizer["TypeCard"],
|
||||
ItemTypes.Note => Localizer["TypeNote"],
|
||||
ItemType.Login => Localizer["TypeLogin"],
|
||||
ItemType.Alias => Localizer["TypeAlias"],
|
||||
ItemType.CreditCard => Localizer["TypeCard"],
|
||||
ItemType.Note => Localizer["TypeNote"],
|
||||
_ => itemType
|
||||
};
|
||||
}
|
||||
@@ -334,10 +335,10 @@
|
||||
{
|
||||
var svg = itemType switch
|
||||
{
|
||||
ItemTypes.Login => """<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" /></svg>""",
|
||||
ItemTypes.Alias => """<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>""",
|
||||
ItemTypes.CreditCard => """<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" /></svg>""",
|
||||
ItemTypes.Note => """<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>""",
|
||||
ItemType.Login => """<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" /></svg>""",
|
||||
ItemType.Alias => """<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" /></svg>""",
|
||||
ItemType.CreditCard => """<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" /></svg>""",
|
||||
ItemType.Note => """<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>""",
|
||||
_ => """<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>"""
|
||||
};
|
||||
return new MarkupString(svg);
|
||||
@@ -368,7 +369,7 @@
|
||||
/// <summary>
|
||||
/// The item type to create.
|
||||
/// </summary>
|
||||
public string ItemType { get; set; } = ItemTypes.Alias;
|
||||
public string ItemType { get; set; } = ItemTypeClass.Alias;
|
||||
|
||||
/// <summary>
|
||||
/// The service name.
|
||||
|
||||
@@ -71,7 +71,7 @@ else
|
||||
}
|
||||
|
||||
@* Notes Section - When visible (left side for non-Note types) *@
|
||||
@if (ShouldShowField(FieldKey.NotesContent) && Obj.ItemType != ItemTypes.Note)
|
||||
@if (ShouldShowField(FieldKey.NotesContent) && Obj.ItemType != ItemType.Note)
|
||||
{
|
||||
<div class="col-span-1 md:col-span-1 lg:col-span-1">
|
||||
<RemovableSection CanRemove="@CanRemoveField(FieldKey.NotesContent)" OnRemove="() => RemoveOptionalField(FieldKey.NotesContent)">
|
||||
@@ -206,7 +206,7 @@ else
|
||||
}
|
||||
</div>
|
||||
}
|
||||
else if (Obj.ItemType == ItemTypes.Login && !ManuallyAddedFields.Contains(FieldKey.LoginEmail))
|
||||
else if (Obj.ItemType == ItemType.Login && !ManuallyAddedFields.Contains(FieldKey.LoginEmail))
|
||||
{
|
||||
@* Show + Email button for Login type when email is not visible *@
|
||||
<div class="col-span-6">
|
||||
@@ -232,7 +232,7 @@ else
|
||||
}
|
||||
|
||||
@* Alias Identity Section - For Alias type *@
|
||||
@if (Obj.ItemType == ItemTypes.Alias)
|
||||
@if (Obj.ItemType == ItemType.Alias)
|
||||
{
|
||||
<div class="col-span-1 md:col-span-1 lg:col-span-2">
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
@@ -276,7 +276,7 @@ else
|
||||
}
|
||||
|
||||
@* Credit Card Section - For CreditCard type *@
|
||||
@if (Obj.ItemType == ItemTypes.CreditCard)
|
||||
@if (Obj.ItemType == ItemType.CreditCard)
|
||||
{
|
||||
<div class="col-span-1 md:col-span-1 lg:col-span-2">
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
@@ -318,7 +318,7 @@ else
|
||||
}
|
||||
|
||||
@* Notes Section - For Note type (main content area) *@
|
||||
@if (Obj.ItemType == ItemTypes.Note)
|
||||
@if (Obj.ItemType == ItemType.Note)
|
||||
{
|
||||
<div class="col-span-1 md:col-span-1 lg:col-span-2">
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
@@ -519,7 +519,7 @@ else
|
||||
/// </summary>
|
||||
private bool HasLoginFields()
|
||||
{
|
||||
return Obj.ItemType == ItemTypes.Login || Obj.ItemType == ItemTypes.Alias;
|
||||
return Obj.ItemType == ItemType.Login || Obj.ItemType == ItemType.Alias;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -789,7 +789,7 @@ else
|
||||
}
|
||||
|
||||
// Generate alias for Alias type in create mode
|
||||
if (newType == ItemTypes.Alias && !EditMode && !HasAliasValues())
|
||||
if (newType == ItemType.Alias && !EditMode && !HasAliasValues())
|
||||
{
|
||||
await GenerateRandomAlias();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
@using AliasVault.RazorComponents.Tables
|
||||
@using AliasVault.Client.Main.Models
|
||||
@using AliasVault.Client.Main.Components.Items
|
||||
@using AliasClientDb.Models
|
||||
@using AliasVault.Client.Main.Components.Folders
|
||||
@using Microsoft.Extensions.Localization
|
||||
@implements IAsyncDisposable
|
||||
@@ -428,10 +429,10 @@ else
|
||||
{
|
||||
ItemFilterType.Passkeys => filtered.Where(x => x.HasPasskey),
|
||||
ItemFilterType.Attachments => filtered.Where(x => x.HasAttachment),
|
||||
ItemFilterType.Login => filtered.Where(x => x.ItemType == ItemTypes.Login),
|
||||
ItemFilterType.Alias => filtered.Where(x => x.ItemType == ItemTypes.Alias),
|
||||
ItemFilterType.CreditCard => filtered.Where(x => x.ItemType == ItemTypes.CreditCard),
|
||||
ItemFilterType.Note => filtered.Where(x => x.ItemType == ItemTypes.Note),
|
||||
ItemFilterType.Login => filtered.Where(x => x.ItemType == ItemType.Login),
|
||||
ItemFilterType.Alias => filtered.Where(x => x.ItemType == ItemType.Alias),
|
||||
ItemFilterType.CreditCard => filtered.Where(x => x.ItemType == ItemType.CreditCard),
|
||||
ItemFilterType.Note => filtered.Where(x => x.ItemType == ItemType.Note),
|
||||
_ => filtered, // All
|
||||
};
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ else
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
<div class="items-center flex space-x-4">
|
||||
<ItemIcon
|
||||
ItemType="@(Item.ItemType ?? ItemTypes.Login)"
|
||||
ItemType="@(Item.ItemType ?? ItemType.Login)"
|
||||
Logo="@Item.Logo?.FileData"
|
||||
CardNumber="@GetCardNumber()"
|
||||
AltText="@(Item.Name ?? "Item")"
|
||||
@@ -78,7 +78,7 @@ else
|
||||
</div>
|
||||
|
||||
@* Recent emails - only for Login/Alias *@
|
||||
@if ((Item.ItemType == ItemTypes.Login || Item.ItemType == ItemTypes.Alias) && !string.IsNullOrEmpty(GetEmailAddress()))
|
||||
@if ((Item.ItemType == ItemType.Login || Item.ItemType == ItemType.Alias) && !string.IsNullOrEmpty(GetEmailAddress()))
|
||||
{
|
||||
<RecentEmails EmailAddress="@GetEmailAddress()" />
|
||||
}
|
||||
@@ -90,7 +90,7 @@ else
|
||||
}
|
||||
|
||||
@* Notes - if present (left column for non-Note types) *@
|
||||
@if (Item.ItemType != ItemTypes.Note && GroupedFields.TryGetValue(FieldCategory.Notes, out var notesFields) && notesFields.Count > 0)
|
||||
@if (Item.ItemType != ItemType.Note && GroupedFields.TryGetValue(FieldCategory.Notes, out var notesFields) && notesFields.Count > 0)
|
||||
{
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
<h3 class="mb-4 text-xl font-semibold dark:text-white">@Localizer["NotesSection"]</h3>
|
||||
@@ -113,7 +113,7 @@ else
|
||||
@* Right column *@
|
||||
<div class="col-span-1 md:col-span-2 lg:col-span-2">
|
||||
@* Login fields - for Login/Alias *@
|
||||
@if ((Item.ItemType == ItemTypes.Login || Item.ItemType == ItemTypes.Alias) &&
|
||||
@if ((Item.ItemType == ItemType.Login || Item.ItemType == ItemType.Alias) &&
|
||||
GroupedFields.TryGetValue(FieldCategory.Login, out var loginFields) && loginFields.Count > 0)
|
||||
{
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
@@ -181,7 +181,7 @@ else
|
||||
}
|
||||
|
||||
@* Alias fields - for Alias type only *@
|
||||
@if (Item.ItemType == ItemTypes.Alias &&
|
||||
@if (Item.ItemType == ItemType.Alias &&
|
||||
GroupedFields.TryGetValue(FieldCategory.Alias, out var aliasFields) && aliasFields.Count > 0)
|
||||
{
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
@@ -209,7 +209,7 @@ else
|
||||
}
|
||||
|
||||
@* Card fields - for CreditCard type *@
|
||||
@if (Item.ItemType == ItemTypes.CreditCard &&
|
||||
@if (Item.ItemType == ItemType.CreditCard &&
|
||||
GroupedFields.TryGetValue(FieldCategory.Card, out var cardFields) && cardFields.Count > 0)
|
||||
{
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
@@ -226,7 +226,7 @@ else
|
||||
}
|
||||
|
||||
@* Notes - for Note type (main content area) *@
|
||||
@if (Item.ItemType == ItemTypes.Note && GroupedFields.TryGetValue(FieldCategory.Notes, out var noteTypeNotesFields) && noteTypeNotesFields.Count > 0)
|
||||
@if (Item.ItemType == ItemType.Note && GroupedFields.TryGetValue(FieldCategory.Notes, out var noteTypeNotesFields) && noteTypeNotesFields.Count > 0)
|
||||
{
|
||||
<div class="p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
|
||||
<h3 class="mb-4 text-xl font-semibold dark:text-white">@Localizer["NotesSection"]</h3>
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace AliasClientDb.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Field types for rendering and validation.
|
||||
/// </summary>
|
||||
public static class FieldType
|
||||
{
|
||||
/// <summary>
|
||||
/// Text field type.
|
||||
/// </summary>
|
||||
public const string Text = "Text";
|
||||
|
||||
/// <summary>
|
||||
/// Password field type.
|
||||
/// </summary>
|
||||
public const string Password = "Password";
|
||||
|
||||
/// <summary>
|
||||
/// Hidden field type.
|
||||
/// </summary>
|
||||
public const string Hidden = "Hidden";
|
||||
|
||||
/// <summary>
|
||||
/// Email field type.
|
||||
/// </summary>
|
||||
public const string Email = "Email";
|
||||
|
||||
/// <summary>
|
||||
/// URL field type.
|
||||
/// </summary>
|
||||
public const string URL = "URL";
|
||||
|
||||
/// <summary>
|
||||
/// Date field type.
|
||||
/// </summary>
|
||||
public const string Date = "Date";
|
||||
|
||||
/// <summary>
|
||||
/// Number field type.
|
||||
/// </summary>
|
||||
public const string Number = "Number";
|
||||
|
||||
/// <summary>
|
||||
/// Phone field type.
|
||||
/// </summary>
|
||||
public const string Phone = "Phone";
|
||||
|
||||
/// <summary>
|
||||
/// TextArea field type.
|
||||
/// </summary>
|
||||
public const string TextArea = "TextArea";
|
||||
|
||||
/// <summary>
|
||||
/// All available field types.
|
||||
/// </summary>
|
||||
public static readonly string[] All = { Text, Password, Hidden, Email, URL, Date, Number, Phone, TextArea };
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a string value is a valid field type.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to check.</param>
|
||||
/// <returns>True if the value is a valid field type.</returns>
|
||||
public static bool IsValid(string? value)
|
||||
{
|
||||
return value == Text || value == Password || value == Hidden || value == Email || value == URL || value == Date || value == Number || value == Phone || value == TextArea;
|
||||
}
|
||||
}
|
||||
+12
-13
@@ -1,34 +1,33 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="ItemTypes.cs" company="aliasvault">
|
||||
// Copyright (c) aliasvault. All rights reserved.
|
||||
// Licensed under the AGPLv3 license. See LICENSE.md file in the project root for full license information.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
namespace AliasVault.Client.Main.Models;
|
||||
#nullable enable
|
||||
|
||||
namespace AliasClientDb.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Constants for item types.
|
||||
/// Item types supported by the vault.
|
||||
/// </summary>
|
||||
public static class ItemTypes
|
||||
public static class ItemType
|
||||
{
|
||||
/// <summary>
|
||||
/// Login item type - username/password credentials.
|
||||
/// Login item type.
|
||||
/// </summary>
|
||||
public const string Login = "Login";
|
||||
|
||||
/// <summary>
|
||||
/// Alias item type - login with auto-generated identity.
|
||||
/// Alias item type.
|
||||
/// </summary>
|
||||
public const string Alias = "Alias";
|
||||
|
||||
/// <summary>
|
||||
/// Credit card item type - payment card information.
|
||||
/// CreditCard item type.
|
||||
/// </summary>
|
||||
public const string CreditCard = "CreditCard";
|
||||
|
||||
/// <summary>
|
||||
/// Note item type - secure notes only.
|
||||
/// Note item type.
|
||||
/// </summary>
|
||||
public const string Note = "Note";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Generates FieldKey constants and SystemFieldRegistry for C#, Swift, and Kotlin from TypeScript source.
|
||||
* Generates FieldKey, FieldType, ItemType constants and SystemFieldRegistry for C#, Swift, and Kotlin from TypeScript source.
|
||||
* All type definitions are dynamically extracted from the TypeScript source files.
|
||||
*/
|
||||
|
||||
@@ -10,11 +10,18 @@ const path = require('path');
|
||||
// Paths
|
||||
const REPO_ROOT = path.join(__dirname, '../../..');
|
||||
const TS_SOURCE = path.join(REPO_ROOT, 'core/models/src/vault/FieldKey.ts');
|
||||
const TS_ITEM_SOURCE = path.join(REPO_ROOT, 'core/models/src/vault/Item.ts');
|
||||
const TS_REGISTRY_SOURCE = path.join(REPO_ROOT, 'core/models/src/vault/SystemFieldRegistry.ts');
|
||||
const CS_OUTPUT = path.join(REPO_ROOT, 'apps/server/Databases/AliasClientDb/Models/FieldKey.cs');
|
||||
const CS_FIELD_TYPE_OUTPUT = path.join(REPO_ROOT, 'apps/server/Databases/AliasClientDb/Models/FieldType.cs');
|
||||
const CS_ITEM_TYPE_OUTPUT = path.join(REPO_ROOT, 'apps/server/Databases/AliasClientDb/Models/ItemType.cs');
|
||||
const CS_REGISTRY_OUTPUT = path.join(REPO_ROOT, 'apps/server/Databases/AliasClientDb/Models/SystemFieldRegistry.cs');
|
||||
const SWIFT_OUTPUT = path.join(REPO_ROOT, 'apps/mobile-app/ios/VaultModels/FieldKey.swift');
|
||||
const SWIFT_FIELD_TYPE_OUTPUT = path.join(REPO_ROOT, 'apps/mobile-app/ios/VaultModels/FieldType.swift');
|
||||
const SWIFT_ITEM_TYPE_OUTPUT = path.join(REPO_ROOT, 'apps/mobile-app/ios/VaultModels/ItemType.swift');
|
||||
const KOTLIN_OUTPUT = path.join(REPO_ROOT, 'apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/FieldKey.kt');
|
||||
const KOTLIN_FIELD_TYPE_OUTPUT = path.join(REPO_ROOT, 'apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/FieldType.kt');
|
||||
const KOTLIN_ITEM_TYPE_OUTPUT = path.join(REPO_ROOT, 'apps/mobile-app/android/app/src/main/java/net/aliasvault/app/vaultstore/models/ItemType.kt');
|
||||
|
||||
/**
|
||||
* Parse the TypeScript FieldKey.ts file and extract constants
|
||||
@@ -52,6 +59,58 @@ function parseTypeScriptFieldKeys(tsContent) {
|
||||
return fieldKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse FieldTypes from TypeScript Item.ts source
|
||||
* Returns an array of field type names in order
|
||||
*/
|
||||
function parseFieldTypes(tsContent) {
|
||||
const fieldTypes = [];
|
||||
|
||||
// Find the FieldTypes constant
|
||||
const match = tsContent.match(/export const FieldTypes\s*=\s*\{([^}]+)\}/s);
|
||||
if (!match) {
|
||||
console.warn('Warning: Could not find FieldTypes in source');
|
||||
return fieldTypes;
|
||||
}
|
||||
|
||||
const body = match[1];
|
||||
// Match each type: Text: 'Text',
|
||||
const typeRegex = /(\w+):\s*'(\w+)'/g;
|
||||
let typeMatch;
|
||||
|
||||
while ((typeMatch = typeRegex.exec(body)) !== null) {
|
||||
fieldTypes.push(typeMatch[1]);
|
||||
}
|
||||
|
||||
return fieldTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse ItemTypes from TypeScript Item.ts source
|
||||
* Returns an array of item type names in order
|
||||
*/
|
||||
function parseItemTypes(tsContent) {
|
||||
const itemTypes = [];
|
||||
|
||||
// Find the ItemTypes constant
|
||||
const match = tsContent.match(/export const ItemTypes\s*=\s*\{([^}]+)\}/s);
|
||||
if (!match) {
|
||||
console.warn('Warning: Could not find ItemTypes in source');
|
||||
return itemTypes;
|
||||
}
|
||||
|
||||
const body = match[1];
|
||||
// Match each type: Login: 'Login',
|
||||
const typeRegex = /(\w+):\s*'(\w+)'/g;
|
||||
let typeMatch;
|
||||
|
||||
while ((typeMatch = typeRegex.exec(body)) !== null) {
|
||||
itemTypes.push(typeMatch[1]);
|
||||
}
|
||||
|
||||
return itemTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse FieldCategories from TypeScript source
|
||||
* Returns an array of category names in order
|
||||
@@ -284,6 +343,282 @@ object FieldKey {`;
|
||||
return header + '\n' + fields + footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate C# static class for FieldType
|
||||
*/
|
||||
function generateCSharpFieldType(fieldTypes) {
|
||||
const header = `// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace AliasClientDb.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Field types for rendering and validation.
|
||||
/// </summary>
|
||||
public static class FieldType
|
||||
{`;
|
||||
|
||||
const fields = fieldTypes
|
||||
.map(type => {
|
||||
return ` /// <summary>
|
||||
/// ${type} field type.
|
||||
/// </summary>
|
||||
public const string ${type} = "${type}";`;
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
const allTypes = `
|
||||
|
||||
/// <summary>
|
||||
/// All available field types.
|
||||
/// </summary>
|
||||
public static readonly string[] All = { ${fieldTypes.map(t => t).join(', ')} };
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a string value is a valid field type.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to check.</param>
|
||||
/// <returns>True if the value is a valid field type.</returns>
|
||||
public static bool IsValid(string? value)
|
||||
{
|
||||
return ${fieldTypes.map(t => `value == ${t}`).join(' || ')};
|
||||
}`;
|
||||
|
||||
const footer = `
|
||||
}
|
||||
`;
|
||||
|
||||
return header + '\n' + fields + allTypes + footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate C# static class for ItemType
|
||||
*/
|
||||
function generateCSharpItemType(itemTypes) {
|
||||
const header = `// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace AliasClientDb.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Item types supported by the vault.
|
||||
/// </summary>
|
||||
public static class ItemType
|
||||
{`;
|
||||
|
||||
const fields = itemTypes
|
||||
.map(type => {
|
||||
return ` /// <summary>
|
||||
/// ${type} item type.
|
||||
/// </summary>
|
||||
public const string ${type} = "${type}";`;
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
const allTypes = `
|
||||
|
||||
/// <summary>
|
||||
/// All available item types.
|
||||
/// </summary>
|
||||
public static readonly string[] All = { ${itemTypes.map(t => t).join(', ')} };
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a string value is a valid item type.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to check.</param>
|
||||
/// <returns>True if the value is a valid item type.</returns>
|
||||
public static bool IsValid(string? value)
|
||||
{
|
||||
return ${itemTypes.map(t => `value == ${t}`).join(' || ')};
|
||||
}`;
|
||||
|
||||
const footer = `
|
||||
}
|
||||
`;
|
||||
|
||||
return header + '\n' + fields + allTypes + footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Swift struct for FieldType
|
||||
*/
|
||||
function generateSwiftFieldType(fieldTypes) {
|
||||
const header = `// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Field types for rendering and validation.
|
||||
public struct FieldType {`;
|
||||
|
||||
const fields = fieldTypes
|
||||
.map(type => {
|
||||
// Convert PascalCase to camelCase for Swift
|
||||
const swiftName = type.charAt(0).toLowerCase() + type.slice(1);
|
||||
return ` /// ${type} field type.
|
||||
public static let ${swiftName} = "${type}"`;
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
const allTypes = `
|
||||
|
||||
/// All available field types.
|
||||
public static let all = [${fieldTypes.map(t => t.charAt(0).toLowerCase() + t.slice(1)).join(', ')}]
|
||||
|
||||
/// Checks if a string value is a valid field type.
|
||||
public static func isValid(_ value: String?) -> Bool {
|
||||
guard let value = value else { return false }
|
||||
return all.contains(value)
|
||||
}`;
|
||||
|
||||
const footer = `
|
||||
}
|
||||
`;
|
||||
|
||||
return header + '\n' + fields + allTypes + footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Swift struct for ItemType
|
||||
*/
|
||||
function generateSwiftItemType(itemTypes) {
|
||||
const header = `// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Item types supported by the vault.
|
||||
public struct ItemType {`;
|
||||
|
||||
const fields = itemTypes
|
||||
.map(type => {
|
||||
// Convert PascalCase to camelCase for Swift
|
||||
const swiftName = type.charAt(0).toLowerCase() + type.slice(1);
|
||||
return ` /// ${type} item type.
|
||||
public static let ${swiftName} = "${type}"`;
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
const allTypes = `
|
||||
|
||||
/// All available item types.
|
||||
public static let all = [${itemTypes.map(t => t.charAt(0).toLowerCase() + t.slice(1)).join(', ')}]
|
||||
|
||||
/// Checks if a string value is a valid item type.
|
||||
public static func isValid(_ value: String?) -> Bool {
|
||||
guard let value = value else { return false }
|
||||
return all.contains(value)
|
||||
}`;
|
||||
|
||||
const footer = `
|
||||
}
|
||||
`;
|
||||
|
||||
return header + '\n' + fields + allTypes + footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Kotlin object for FieldType
|
||||
*/
|
||||
function generateKotlinFieldType(fieldTypes) {
|
||||
const header = `// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
package net.aliasvault.app.vaultstore.models
|
||||
|
||||
/**
|
||||
* Field types for rendering and validation.
|
||||
*/
|
||||
object FieldType {`;
|
||||
|
||||
const fields = fieldTypes
|
||||
.map(type => {
|
||||
// Convert to SCREAMING_SNAKE_CASE for Kotlin constants
|
||||
const kotlinName = type.replace(/([A-Z])/g, '_$1').toUpperCase().replace(/^_/, '');
|
||||
return ` /**
|
||||
* ${type} field type.
|
||||
*/
|
||||
const val ${kotlinName} = "${type}"`;
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
const allTypes = `
|
||||
|
||||
/**
|
||||
* All available field types.
|
||||
*/
|
||||
val all = listOf(${fieldTypes.map(t => t.replace(/([A-Z])/g, '_$1').toUpperCase().replace(/^_/, '')).join(', ')})
|
||||
|
||||
/**
|
||||
* Checks if a string value is a valid field type.
|
||||
*/
|
||||
fun isValid(value: String?): Boolean {
|
||||
return value in all
|
||||
}`;
|
||||
|
||||
const footer = `
|
||||
}
|
||||
`;
|
||||
|
||||
return header + '\n' + fields + allTypes + footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Kotlin object for ItemType
|
||||
*/
|
||||
function generateKotlinItemType(itemTypes) {
|
||||
const header = `// <auto-generated />
|
||||
// This file is auto-generated from core/models/src/vault/Item.ts
|
||||
// Do not edit this file directly. Run 'npm run generate:models' to regenerate.
|
||||
|
||||
package net.aliasvault.app.vaultstore.models
|
||||
|
||||
/**
|
||||
* Item types supported by the vault.
|
||||
*/
|
||||
object ItemType {`;
|
||||
|
||||
const fields = itemTypes
|
||||
.map(type => {
|
||||
// Convert to SCREAMING_SNAKE_CASE for Kotlin constants
|
||||
const kotlinName = type.replace(/([A-Z])/g, '_$1').toUpperCase().replace(/^_/, '');
|
||||
return ` /**
|
||||
* ${type} item type.
|
||||
*/
|
||||
const val ${kotlinName} = "${type}"`;
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
const allTypes = `
|
||||
|
||||
/**
|
||||
* All available item types.
|
||||
*/
|
||||
val all = listOf(${itemTypes.map(t => t.replace(/([A-Z])/g, '_$1').toUpperCase().replace(/^_/, '')).join(', ')})
|
||||
|
||||
/**
|
||||
* Checks if a string value is a valid item type.
|
||||
*/
|
||||
fun isValid(value: String?): Boolean {
|
||||
return value in all
|
||||
}`;
|
||||
|
||||
const footer = `
|
||||
}
|
||||
`;
|
||||
|
||||
return header + '\n' + fields + allTypes + footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the TypeScript SystemFieldRegistry.ts file and extract field definitions
|
||||
*/
|
||||
@@ -626,6 +961,23 @@ function main() {
|
||||
throw new Error('No field keys found in source file');
|
||||
}
|
||||
|
||||
// Read TypeScript Item.ts source for FieldTypes and ItemTypes
|
||||
if (!fs.existsSync(TS_ITEM_SOURCE)) {
|
||||
throw new Error(`Source file not found: ${TS_ITEM_SOURCE}`);
|
||||
}
|
||||
|
||||
const tsItemContent = fs.readFileSync(TS_ITEM_SOURCE, 'utf8');
|
||||
const fieldTypes = parseFieldTypes(tsItemContent);
|
||||
const itemTypes = parseItemTypes(tsItemContent);
|
||||
|
||||
if (fieldTypes.length === 0) {
|
||||
throw new Error('No field types found in Item.ts source file');
|
||||
}
|
||||
|
||||
if (itemTypes.length === 0) {
|
||||
throw new Error('No item types found in Item.ts source file');
|
||||
}
|
||||
|
||||
// Read TypeScript SystemFieldRegistry source
|
||||
if (!fs.existsSync(TS_REGISTRY_SOURCE)) {
|
||||
throw new Error(`Source file not found: ${TS_REGISTRY_SOURCE}`);
|
||||
@@ -644,6 +996,8 @@ function main() {
|
||||
}
|
||||
|
||||
console.log(`Parsed ${Object.keys(fieldKeys).length} field keys`);
|
||||
console.log(`Parsed ${fieldTypes.length} field types: ${fieldTypes.join(', ')}`);
|
||||
console.log(`Parsed ${itemTypes.length} item types: ${itemTypes.join(', ')}`);
|
||||
console.log(`Parsed ${categories.length} field categories: ${categories.join(', ')}`);
|
||||
console.log(`Parsed ${itemTypeFieldConfigProps.length} ItemTypeFieldConfig properties`);
|
||||
console.log(`Parsed ${systemFieldDefProps.length} SystemFieldDefinition properties`);
|
||||
@@ -655,6 +1009,18 @@ function main() {
|
||||
fs.writeFileSync(CS_OUTPUT, csContent, 'utf8');
|
||||
console.log(`Generated: ${CS_OUTPUT}`);
|
||||
|
||||
// Generate C# FieldType
|
||||
ensureDir(CS_FIELD_TYPE_OUTPUT);
|
||||
const csFieldTypeContent = generateCSharpFieldType(fieldTypes);
|
||||
fs.writeFileSync(CS_FIELD_TYPE_OUTPUT, csFieldTypeContent, 'utf8');
|
||||
console.log(`Generated: ${CS_FIELD_TYPE_OUTPUT}`);
|
||||
|
||||
// Generate C# ItemType
|
||||
ensureDir(CS_ITEM_TYPE_OUTPUT);
|
||||
const csItemTypeContent = generateCSharpItemType(itemTypes);
|
||||
fs.writeFileSync(CS_ITEM_TYPE_OUTPUT, csItemTypeContent, 'utf8');
|
||||
console.log(`Generated: ${CS_ITEM_TYPE_OUTPUT}`);
|
||||
|
||||
// Generate C# SystemFieldRegistry
|
||||
ensureDir(CS_REGISTRY_OUTPUT);
|
||||
const csRegistryContent = generateCSharpSystemFieldRegistry(
|
||||
@@ -666,18 +1032,42 @@ function main() {
|
||||
fs.writeFileSync(CS_REGISTRY_OUTPUT, csRegistryContent, 'utf8');
|
||||
console.log(`Generated: ${CS_REGISTRY_OUTPUT}`);
|
||||
|
||||
// Generate Swift
|
||||
// Generate Swift FieldKey
|
||||
ensureDir(SWIFT_OUTPUT);
|
||||
const swiftContent = generateSwift(fieldKeys);
|
||||
fs.writeFileSync(SWIFT_OUTPUT, swiftContent, 'utf8');
|
||||
console.log(`Generated: ${SWIFT_OUTPUT}`);
|
||||
|
||||
// Generate Kotlin
|
||||
// Generate Swift FieldType
|
||||
ensureDir(SWIFT_FIELD_TYPE_OUTPUT);
|
||||
const swiftFieldTypeContent = generateSwiftFieldType(fieldTypes);
|
||||
fs.writeFileSync(SWIFT_FIELD_TYPE_OUTPUT, swiftFieldTypeContent, 'utf8');
|
||||
console.log(`Generated: ${SWIFT_FIELD_TYPE_OUTPUT}`);
|
||||
|
||||
// Generate Swift ItemType
|
||||
ensureDir(SWIFT_ITEM_TYPE_OUTPUT);
|
||||
const swiftItemTypeContent = generateSwiftItemType(itemTypes);
|
||||
fs.writeFileSync(SWIFT_ITEM_TYPE_OUTPUT, swiftItemTypeContent, 'utf8');
|
||||
console.log(`Generated: ${SWIFT_ITEM_TYPE_OUTPUT}`);
|
||||
|
||||
// Generate Kotlin FieldKey
|
||||
ensureDir(KOTLIN_OUTPUT);
|
||||
const kotlinContent = generateKotlin(fieldKeys);
|
||||
fs.writeFileSync(KOTLIN_OUTPUT, kotlinContent, 'utf8');
|
||||
console.log(`Generated: ${KOTLIN_OUTPUT}`);
|
||||
|
||||
// Generate Kotlin FieldType
|
||||
ensureDir(KOTLIN_FIELD_TYPE_OUTPUT);
|
||||
const kotlinFieldTypeContent = generateKotlinFieldType(fieldTypes);
|
||||
fs.writeFileSync(KOTLIN_FIELD_TYPE_OUTPUT, kotlinFieldTypeContent, 'utf8');
|
||||
console.log(`Generated: ${KOTLIN_FIELD_TYPE_OUTPUT}`);
|
||||
|
||||
// Generate Kotlin ItemType
|
||||
ensureDir(KOTLIN_ITEM_TYPE_OUTPUT);
|
||||
const kotlinItemTypeContent = generateKotlinItemType(itemTypes);
|
||||
fs.writeFileSync(KOTLIN_ITEM_TYPE_OUTPUT, kotlinItemTypeContent, 'utf8');
|
||||
console.log(`Generated: ${KOTLIN_ITEM_TYPE_OUTPUT}`);
|
||||
|
||||
console.log('\nCode generation complete!');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user