@happyvertical/smrt-languages 0.56.1 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import { ObjectRegistry } from "@happyvertical/smrt-core";
3
3
  import { getPackageConfig } from "@happyvertical/smrt-config";
4
4
  import { getTenantId } from "@happyvertical/smrt-tenancy";
5
5
  //#region src/__smrt-register__.ts
6
- ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-languages","packageVersion":"0.56.1","objects":{"@happyvertical/smrt-languages:LanguageOverrideCollection":{"name":"languageoverridecollection","className":"LanguageOverrideCollection","qualifiedName":"@happyvertical/smrt-languages:LanguageOverrideCollection","collection":"languageoverrides","filePath":"/home/runner/work/smrt/smrt/packages/languages/src/collections/LanguageOverrideCollection.ts","packageName":"@happyvertical/smrt-languages","fields":{},"methods":{"getAppOverride":{"name":"getAppOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"locale","type":"string","optional":false}],"returnType":"Promise<LanguageOverride | null>","isStatic":false,"isPublic":true},"getTenantOverride":{"name":"getTenantOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"locale","type":"string","optional":false},{"name":"tenantId","type":"string","optional":false}],"returnType":"Promise<LanguageOverride | null>","isStatic":false,"isPublic":true},"getResolutionLayers":{"name":"getResolutionLayers","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"locale","type":"string","optional":false},{"name":"tenantId","type":"string | null","optional":true,"unionBranches":[{"type":"string"},{"type":"null"}]}],"returnType":"Promise<object>","isStatic":false,"isPublic":true},"listTenantOverrides":{"name":"listTenantOverrides","async":true,"parameters":[{"name":"tenantId","type":"string","optional":false}],"returnType":"Promise<LanguageOverride[]>","isStatic":false,"isPublic":true},"listUnreviewedAutoTranslations":{"name":"listUnreviewedAutoTranslations","async":true,"parameters":[{"name":"options","type":"object","optional":true,"memberTypes":["string","number"]}],"returnType":"Promise<LanguageOverride[]>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_language_overrides"},"extends":"SmrtCollection","extendsTypeArg":"LanguageOverride","exportName":"LanguageOverrideCollection","collectionExportName":"LanguageOverrideCollectionCollection","schema":{"tableName":"_smrt_language_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_language_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"locale\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT NOT NULL,\\n \\"auto_generated\\" BOOLEAN NOT NULL DEFAULT FALSE,\\n \\"source_hash\\" TEXT,\\n \\"ai_model\\" TEXT,\\n \\"reviewed_at\\" TEXT,\\n \\"reviewed_by\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"locale":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":true,"unique":false},"auto_generated":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"source_hash":{"type":"TEXT","notNull":false,"unique":false},"ai_model":{"type":"TEXT","notNull":false,"unique":false},"reviewed_at":{"type":"TEXT","notNull":false,"unique":false},"reviewed_by":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_language_overrides_key_locale_idx","columns":["key","locale","context"],"unique":true},{"name":"_smrt_language_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_language_overrides_created_at_idx","columns":["created_at"]}],"version":"91442913"},"importPath":"@happyvertical/smrt-languages"},"@happyvertical/smrt-languages:LanguageOverride":{"name":"languageoverride","className":"LanguageOverride","qualifiedName":"@happyvertical/smrt-languages:LanguageOverride","collection":"languageoverrides","filePath":"/home/runner/work/smrt/smrt/packages/languages/src/models/LanguageOverride.ts","packageName":"@happyvertical/smrt-languages","fields":{"key":{"type":"text","required":true,"default":"","_meta":{"required":true}},"locale":{"type":"text","required":true,"default":"","_meta":{"required":true}},"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true}},"template":{"type":"text","required":true,"_meta":{"required":true}},"auto_generated":{"type":"boolean","required":true,"default":false,"_meta":{"required":true,"default":false}},"source_hash":{"type":"text","required":false,"_meta":{"nullable":true}},"ai_model":{"type":"text","required":false,"_meta":{"nullable":true}},"reviewed_at":{"type":"text","required":false,"_meta":{"nullable":true}},"reviewed_by":{"type":"text","required":false,"_meta":{"nullable":true}}},"methods":{"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"delete":{"name":"delete","async":true,"parameters":[],"returnType":"Promise<void>","isStatic":false,"isPublic":true},"approve":{"name":"approve","async":true,"parameters":[{"name":"reviewerId","type":"string","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_language_overrides","conflictColumns":["key","locale","context"],"api":{"include":["list","get","create","update","delete"]},"cli":{"include":["list","get","create","update","delete","approve"],"skipApiCheck":true},"mcp":{"include":[]}},"extends":"SmrtObject","exportName":"LanguageOverride","collectionExportName":"LanguageOverrideCollection","validationRules":[{"field":"key","rule":"required","fieldType":"text"},{"field":"locale","rule":"required","fieldType":"text"},{"field":"template","rule":"required","fieldType":"text"},{"field":"auto_generated","rule":"required","fieldType":"boolean"}],"schema":{"tableName":"_smrt_language_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_language_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"locale\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT NOT NULL,\\n \\"auto_generated\\" BOOLEAN NOT NULL DEFAULT FALSE,\\n \\"source_hash\\" TEXT,\\n \\"ai_model\\" TEXT,\\n \\"reviewed_at\\" TEXT,\\n \\"reviewed_by\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"locale":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":true,"unique":false},"auto_generated":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"source_hash":{"type":"TEXT","notNull":false,"unique":false},"ai_model":{"type":"TEXT","notNull":false,"unique":false},"reviewed_at":{"type":"TEXT","notNull":false,"unique":false},"reviewed_by":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_language_overrides_key_locale_idx","columns":["key","locale","context"],"unique":true},{"name":"_smrt_language_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_language_overrides_created_at_idx","columns":["created_at"]}],"version":"91442913"},"importPath":"@happyvertical/smrt-languages"},"@happyvertical/smrt-languages:LanguageTranslationTask":{"name":"languagetranslationtask","className":"LanguageTranslationTask","qualifiedName":"@happyvertical/smrt-languages:LanguageTranslationTask","collection":"languagetranslationtasks","description":"SmrtObject that owns the translation job's execute method. The TaskRunner resolves jobs by objectType so the registered class name needs to match what enqueueTranslationJob writes.","filePath":"/home/runner/work/smrt/smrt/packages/languages/src/jobs/translation-job.ts","packageName":"@happyvertical/smrt-languages","fields":{},"methods":{"execute":{"name":"execute","async":true,"parameters":[{"name":"args","type":"TranslationJobPayload","optional":false}],"returnType":"Promise<object>","isStatic":false,"isPublic":true}},"decoratorConfig":{"api":{"include":[]},"cli":{"include":[]},"mcp":{"include":[]}},"extends":"SmrtObject","exportName":"LanguageTranslationTask","collectionExportName":"LanguageTranslationTaskCollection","schema":{"tableName":"language_translation_tasks","ddl":"CREATE TABLE IF NOT EXISTS \\"language_translation_tasks\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"}},"indexes":[{"name":"language_translation_tasks_slug_context_idx","columns":["slug","context"],"unique":true},{"name":"language_translation_tasks_created_at_idx","columns":["created_at"]}],"version":"2cfc8812"},"importPath":"@happyvertical/smrt-languages/jobs"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-features","@happyvertical/smrt-jobs","@happyvertical/smrt-prompts","@happyvertical/smrt-tenancy"],"browser":{"status":"server-only","issues":["#3615","#3618","#3624","#3627"],"reason":"node:crypto","via":["@happyvertical/smrt-features","@happyvertical/smrt-jobs","@happyvertical/smrt-tenancy"]},"stampsConstructors":true}`));
6
+ ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-languages","packageVersion":"0.57.0","objects":{"@happyvertical/smrt-languages:LanguageOverrideCollection":{"name":"languageoverridecollection","className":"LanguageOverrideCollection","qualifiedName":"@happyvertical/smrt-languages:LanguageOverrideCollection","collection":"languageoverrides","filePath":"/home/runner/work/smrt/smrt/packages/languages/src/collections/LanguageOverrideCollection.ts","packageName":"@happyvertical/smrt-languages","fields":{},"methods":{"getAppOverride":{"name":"getAppOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"locale","type":"string","optional":false}],"returnType":"Promise<LanguageOverride | null>","isStatic":false,"isPublic":true},"getTenantOverride":{"name":"getTenantOverride","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"locale","type":"string","optional":false},{"name":"tenantId","type":"string","optional":false}],"returnType":"Promise<LanguageOverride | null>","isStatic":false,"isPublic":true},"getResolutionLayers":{"name":"getResolutionLayers","async":true,"parameters":[{"name":"key","type":"string","optional":false},{"name":"locale","type":"string","optional":false},{"name":"tenantId","type":"string | null","optional":true,"unionBranches":[{"type":"string"},{"type":"null"}]}],"returnType":"Promise<object>","isStatic":false,"isPublic":true},"listTenantOverrides":{"name":"listTenantOverrides","async":true,"parameters":[{"name":"tenantId","type":"string","optional":false}],"returnType":"Promise<LanguageOverride[]>","isStatic":false,"isPublic":true},"listUnreviewedAutoTranslations":{"name":"listUnreviewedAutoTranslations","async":true,"parameters":[{"name":"options","type":"object","optional":true,"memberTypes":["string","number"]}],"returnType":"Promise<LanguageOverride[]>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_language_overrides","api":{"include":["list","get","create","update","delete"]},"mcp":{"include":[]},"cli":{"include":["list","get","create","update","delete"],"skipApiCheck":true}},"extends":"SmrtCollection","extendsTypeArg":"LanguageOverride","exportName":"LanguageOverrideCollection","collectionExportName":"LanguageOverrideCollectionCollection","schema":{"tableName":"_smrt_language_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_language_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"locale\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT NOT NULL,\\n \\"auto_generated\\" BOOLEAN NOT NULL DEFAULT FALSE,\\n \\"source_hash\\" TEXT,\\n \\"ai_model\\" TEXT,\\n \\"reviewed_at\\" TEXT,\\n \\"reviewed_by\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"locale":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":true,"unique":false},"auto_generated":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"source_hash":{"type":"TEXT","notNull":false,"unique":false},"ai_model":{"type":"TEXT","notNull":false,"unique":false},"reviewed_at":{"type":"TEXT","notNull":false,"unique":false},"reviewed_by":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_language_overrides_key_locale_idx","columns":["key","locale","context"],"unique":true},{"name":"_smrt_language_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_language_overrides_created_at_idx","columns":["created_at"]}],"version":"91442913"},"importPath":"@happyvertical/smrt-languages"},"@happyvertical/smrt-languages:LanguageTranslationTask":{"name":"languagetranslationtask","className":"LanguageTranslationTask","qualifiedName":"@happyvertical/smrt-languages:LanguageTranslationTask","collection":"languagetranslationtasks","description":"SmrtObject that owns the translation job's execute method. The TaskRunner resolves jobs by objectType so the registered class name needs to match what enqueueTranslationJob writes.","filePath":"/home/runner/work/smrt/smrt/packages/languages/src/jobs/translation-job.ts","packageName":"@happyvertical/smrt-languages","fields":{},"methods":{"execute":{"name":"execute","async":true,"parameters":[{"name":"args","type":"TranslationJobPayload","optional":false}],"returnType":"Promise<object>","isStatic":false,"isPublic":true}},"decoratorConfig":{"api":{"include":[]},"cli":{"include":[]},"mcp":{"include":[]}},"extends":"SmrtObject","exportName":"LanguageTranslationTask","collectionExportName":"LanguageTranslationTaskCollection","schema":{"tableName":"language_translation_tasks","ddl":"CREATE TABLE IF NOT EXISTS \\"language_translation_tasks\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"}},"indexes":[{"name":"language_translation_tasks_slug_context_idx","columns":["slug","context"],"unique":true},{"name":"language_translation_tasks_created_at_idx","columns":["created_at"]}],"version":"2cfc8812"},"importPath":"@happyvertical/smrt-languages/jobs"},"@happyvertical/smrt-languages:LanguageOverride":{"name":"languageoverride","className":"LanguageOverride","qualifiedName":"@happyvertical/smrt-languages:LanguageOverride","collection":"languageoverrides","filePath":"/home/runner/work/smrt/smrt/packages/languages/src/models/LanguageOverride.ts","packageName":"@happyvertical/smrt-languages","fields":{"key":{"type":"text","required":true,"default":"","_meta":{"required":true}},"locale":{"type":"text","required":true,"default":"","_meta":{"required":true}},"tenantId":{"type":"text","required":false,"_meta":{"sqlType":"UUID","nullable":true}},"template":{"type":"text","required":true,"_meta":{"required":true}},"auto_generated":{"type":"boolean","required":true,"default":false,"_meta":{"required":true,"default":false}},"source_hash":{"type":"text","required":false,"_meta":{"nullable":true}},"ai_model":{"type":"text","required":false,"_meta":{"nullable":true}},"reviewed_at":{"type":"text","required":false,"_meta":{"nullable":true}},"reviewed_by":{"type":"text","required":false,"_meta":{"nullable":true}}},"methods":{"save":{"name":"save","async":true,"parameters":[],"returnType":"Promise<this>","isStatic":false,"isPublic":true},"delete":{"name":"delete","async":true,"parameters":[],"returnType":"Promise<void>","isStatic":false,"isPublic":true},"approve":{"name":"approve","async":true,"parameters":[{"name":"reviewerId","type":"string","optional":false}],"returnType":"Promise<this>","isStatic":false,"isPublic":true}},"decoratorConfig":{"tableName":"_smrt_language_overrides","conflictColumns":["key","locale","context"],"api":{"include":["list","get","create","update","delete"]},"cli":{"include":["list","get","create","update","delete","approve"],"skipApiCheck":true},"mcp":{"include":[]}},"extends":"SmrtObject","exportName":"LanguageOverride","collectionExportName":"LanguageOverrideCollection","validationRules":[{"field":"key","rule":"required","fieldType":"text"},{"field":"locale","rule":"required","fieldType":"text"},{"field":"template","rule":"required","fieldType":"text"},{"field":"auto_generated","rule":"required","fieldType":"boolean"}],"schema":{"tableName":"_smrt_language_overrides","ddl":"CREATE TABLE IF NOT EXISTS \\"_smrt_language_overrides\\" (\\n \\"id\\" UUID PRIMARY KEY NOT NULL,\\n \\"slug\\" TEXT NOT NULL,\\n \\"context\\" TEXT NOT NULL DEFAULT '',\\n \\"created_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"updated_at\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\n \\"key\\" TEXT NOT NULL DEFAULT '',\\n \\"locale\\" TEXT NOT NULL DEFAULT '',\\n \\"tenant_id\\" UUID,\\n \\"template\\" TEXT NOT NULL,\\n \\"auto_generated\\" BOOLEAN NOT NULL DEFAULT FALSE,\\n \\"source_hash\\" TEXT,\\n \\"ai_model\\" TEXT,\\n \\"reviewed_at\\" TEXT,\\n \\"reviewed_by\\" TEXT\\n);","columns":{"id":{"type":"UUID","primaryKey":true,"referenceKind":"id","notNull":true},"slug":{"type":"TEXT","notNull":true},"context":{"type":"TEXT","notNull":true,"default":""},"created_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"updated_at":{"type":"TIMESTAMP","notNull":true,"default":"current_timestamp"},"key":{"type":"TEXT","notNull":true,"unique":false,"default":""},"locale":{"type":"TEXT","notNull":true,"unique":false,"default":""},"tenant_id":{"type":"UUID","notNull":false,"unique":false},"template":{"type":"TEXT","notNull":true,"unique":false},"auto_generated":{"type":"BOOLEAN","notNull":true,"unique":false,"default":false},"source_hash":{"type":"TEXT","notNull":false,"unique":false},"ai_model":{"type":"TEXT","notNull":false,"unique":false},"reviewed_at":{"type":"TEXT","notNull":false,"unique":false},"reviewed_by":{"type":"TEXT","notNull":false,"unique":false}},"indexes":[{"name":"_smrt_language_overrides_key_locale_idx","columns":["key","locale","context"],"unique":true},{"name":"_smrt_language_overrides_slug_context_idx","columns":["slug","context"]},{"name":"_smrt_language_overrides_created_at_idx","columns":["created_at"]}],"version":"91442913"},"importPath":"@happyvertical/smrt-languages"}},"moduleType":"smrt","smrtDependencies":["@happyvertical/smrt-core","@happyvertical/smrt-features","@happyvertical/smrt-jobs","@happyvertical/smrt-prompts","@happyvertical/smrt-tenancy"],"browser":{"status":"server-only","issues":["#3615","#3618","#3624","#3627"],"reason":"node:crypto","via":["@happyvertical/smrt-features","@happyvertical/smrt-jobs","@happyvertical/smrt-tenancy"]},"stampsConstructors":true}`));
7
7
  //#endregion
8
8
  //#region src/language-resolver.ts
9
9
  var DEFAULT_LOCALE = "en";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/language-resolver.ts","../src/index.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-languages\\\",\\\"packageVersion\\\":\\\"0.56.1\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-languages:LanguageOverrideCollection\\\":{\\\"name\\\":\\\"languageoverridecollection\\\",\\\"className\\\":\\\"LanguageOverrideCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-languages:LanguageOverrideCollection\\\",\\\"collection\\\":\\\"languageoverrides\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/languages/src/collections/LanguageOverrideCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-languages\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getAppOverride\\\":{\\\"name\\\":\\\"getAppOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"locale\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<LanguageOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTenantOverride\\\":{\\\"name\\\":\\\"getTenantOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"locale\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<LanguageOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getResolutionLayers\\\":{\\\"name\\\":\\\"getResolutionLayers\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"locale\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string | null\\\",\\\"optional\\\":true,\\\"unionBranches\\\":[{\\\"type\\\":\\\"string\\\"},{\\\"type\\\":\\\"null\\\"}]}],\\\"returnType\\\":\\\"Promise<object>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"listTenantOverrides\\\":{\\\"name\\\":\\\"listTenantOverrides\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<LanguageOverride[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"listUnreviewedAutoTranslations\\\":{\\\"name\\\":\\\"listUnreviewedAutoTranslations\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"number\\\"]}],\\\"returnType\\\":\\\"Promise<LanguageOverride[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_language_overrides\\\"},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"LanguageOverride\\\",\\\"exportName\\\":\\\"LanguageOverrideCollection\\\",\\\"collectionExportName\\\":\\\"LanguageOverrideCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_language_overrides\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_language_overrides\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"key\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"locale\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"template\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"auto_generated\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"source_hash\\\\\\\" TEXT,\\\\n \\\\\\\"ai_model\\\\\\\" TEXT,\\\\n \\\\\\\"reviewed_at\\\\\\\" TEXT,\\\\n \\\\\\\"reviewed_by\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"locale\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"template\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"auto_generated\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"source_hash\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ai_model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"reviewed_at\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"reviewed_by\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_language_overrides_key_locale_idx\\\",\\\"columns\\\":[\\\"key\\\",\\\"locale\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_language_overrides_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_language_overrides_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"91442913\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-languages\\\"},\\\"@happyvertical/smrt-languages:LanguageOverride\\\":{\\\"name\\\":\\\"languageoverride\\\",\\\"className\\\":\\\"LanguageOverride\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-languages:LanguageOverride\\\",\\\"collection\\\":\\\"languageoverrides\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/languages/src/models/LanguageOverride.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-languages\\\",\\\"fields\\\":{\\\"key\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"locale\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true}},\\\"template\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"auto_generated\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":true,\\\"default\\\":false,\\\"_meta\\\":{\\\"required\\\":true,\\\"default\\\":false}},\\\"source_hash\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"ai_model\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"reviewed_at\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"reviewed_by\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"delete\\\":{\\\"name\\\":\\\"delete\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"approve\\\":{\\\"name\\\":\\\"approve\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"reviewerId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_language_overrides\\\",\\\"conflictColumns\\\":[\\\"key\\\",\\\"locale\\\",\\\"context\\\"],\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\",\\\"delete\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\",\\\"delete\\\",\\\"approve\\\"],\\\"skipApiCheck\\\":true},\\\"mcp\\\":{\\\"include\\\":[]}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"LanguageOverride\\\",\\\"collectionExportName\\\":\\\"LanguageOverrideCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"key\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"locale\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"template\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"auto_generated\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"boolean\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_language_overrides\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_language_overrides\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"key\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"locale\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"template\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"auto_generated\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"source_hash\\\\\\\" TEXT,\\\\n \\\\\\\"ai_model\\\\\\\" TEXT,\\\\n \\\\\\\"reviewed_at\\\\\\\" TEXT,\\\\n \\\\\\\"reviewed_by\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"locale\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"template\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"auto_generated\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"source_hash\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ai_model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"reviewed_at\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"reviewed_by\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_language_overrides_key_locale_idx\\\",\\\"columns\\\":[\\\"key\\\",\\\"locale\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_language_overrides_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_language_overrides_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"91442913\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-languages\\\"},\\\"@happyvertical/smrt-languages:LanguageTranslationTask\\\":{\\\"name\\\":\\\"languagetranslationtask\\\",\\\"className\\\":\\\"LanguageTranslationTask\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-languages:LanguageTranslationTask\\\",\\\"collection\\\":\\\"languagetranslationtasks\\\",\\\"description\\\":\\\"SmrtObject that owns the translation job's execute method. The TaskRunner resolves jobs by objectType so the registered class name needs to match what enqueueTranslationJob writes.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/languages/src/jobs/translation-job.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-languages\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"execute\\\":{\\\"name\\\":\\\"execute\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"args\\\",\\\"type\\\":\\\"TranslationJobPayload\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<object>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[]},\\\"cli\\\":{\\\"include\\\":[]},\\\"mcp\\\":{\\\"include\\\":[]}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"LanguageTranslationTask\\\",\\\"collectionExportName\\\":\\\"LanguageTranslationTaskCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"language_translation_tasks\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"language_translation_tasks\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"language_translation_tasks_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"language_translation_tasks_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"2cfc8812\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-languages/jobs\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-features\\\",\\\"@happyvertical/smrt-jobs\\\",\\\"@happyvertical/smrt-prompts\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"browser\\\":{\\\"status\\\":\\\"server-only\\\",\\\"issues\\\":[\\\"#3615\\\",\\\"#3618\\\",\\\"#3624\\\",\\\"#3627\\\"],\\\"reason\\\":\\\"node:crypto\\\",\\\"via\\\":[\\\"@happyvertical/smrt-features\\\",\\\"@happyvertical/smrt-jobs\\\",\\\"@happyvertical/smrt-tenancy\\\"]},\\\"stampsConstructors\\\":true}\"));\n","import { getPackageConfig } from '@happyvertical/smrt-config';\nimport { getTenantId } from '@happyvertical/smrt-tenancy';\nimport {\n getCachedLanguage,\n getLanguageCacheGeneration,\n invalidateLanguageCache,\n setCachedLanguage,\n} from './cache.js';\nimport { LanguageOverrideCollection } from './collections/LanguageOverrideCollection.js';\nimport { LanguageRegistry } from './language-registry.js';\nimport type {\n LanguageCacheValue,\n LanguagesPackageConfig,\n ResolvedLanguageString,\n ResolveLanguageStringOptions,\n} from './types.js';\nimport {\n buildLocaleFallbackChain,\n normalizeLocale,\n renderTemplate,\n} from './utils.js';\n\nconst DEFAULT_LOCALE = 'en';\n\nfunction getLanguagesConfig(): LanguagesPackageConfig {\n return getPackageConfig<LanguagesPackageConfig>('languages', {\n defaultLocale: DEFAULT_LOCALE,\n overrides: {},\n });\n}\n\ninterface ResolutionAttempt {\n template: string | null;\n source: ResolvedLanguageString['source'];\n resolvedFromLocale: string;\n}\n\nasync function resolveBaseForLocale(\n key: string,\n locale: string,\n options: ResolveLanguageStringOptions,\n config: LanguagesPackageConfig,\n): Promise<ResolutionAttempt> {\n const tenantId =\n options.tenantId !== undefined ? options.tenantId : (getTenantId() ?? null);\n\n let collection: LanguageOverrideCollection | null = null;\n if (options.db) {\n collection = await LanguageOverrideCollection.create({\n db: options.db,\n });\n }\n\n const cacheDb = collection?.db ?? options.db;\n const cached = getCachedLanguage(key, locale, tenantId, cacheDb);\n if (cached) {\n return {\n template: cached.template,\n source: cached.source,\n resolvedFromLocale: cached.resolvedFromLocale,\n };\n }\n\n // Capture the invalidation generation before the asynchronous layer loads. A\n // write that lands while they are in flight bumps it, and the cache write in\n // `finalize` is then refused rather than repopulating the entry the write\n // just invalidated with the pre-write value.\n const loadedAtGeneration = getLanguageCacheGeneration(key, locale, cacheDb);\n\n // 1. Tenant override (highest precedence among stored layers).\n if (collection && tenantId) {\n const tenantOverride = await collection.getTenantOverride(\n key,\n locale,\n tenantId,\n );\n if (tenantOverride) {\n return finalize({\n key,\n locale,\n tenantId,\n db: cacheDb,\n loadedAtGeneration,\n attempt: {\n template: tenantOverride.template,\n source: 'tenant',\n resolvedFromLocale: locale,\n },\n });\n }\n }\n\n // 2. App-level override (incl. AI auto-translations).\n if (collection) {\n const appOverride = await collection.getAppOverride(key, locale);\n if (appOverride) {\n return finalize({\n key,\n locale,\n tenantId,\n db: cacheDb,\n loadedAtGeneration,\n attempt: {\n template: appOverride.template,\n source: 'app',\n resolvedFromLocale: locale,\n },\n });\n }\n }\n\n // 3. File-config override. Locale keys in user-authored config files\n // commonly come in mixed case (`fr-ca`, `Fr-CA`, etc.); normalize lookup so\n // config matches the same way the DB and code-default layers do.\n const configForKey = config.overrides?.[key];\n const configTemplate = lookupNormalizedLocale(configForKey, locale);\n if (typeof configTemplate === 'string') {\n return finalize({\n key,\n locale,\n tenantId,\n db: cacheDb,\n loadedAtGeneration,\n attempt: {\n template: configTemplate,\n source: 'config',\n resolvedFromLocale: locale,\n },\n });\n }\n\n // 4. Code default.\n const definition = LanguageRegistry.get(key, locale);\n if (definition) {\n return finalize({\n key,\n locale,\n tenantId,\n db: cacheDb,\n loadedAtGeneration,\n attempt: {\n template: definition.template,\n source: 'code',\n resolvedFromLocale: locale,\n },\n });\n }\n\n return {\n template: null,\n source: 'missing',\n resolvedFromLocale: locale,\n };\n}\n\nfunction lookupNormalizedLocale(\n bag: Record<string, string> | undefined,\n locale: string,\n): string | undefined {\n if (!bag) return undefined;\n // Fast path: exact match (most file configs use the canonical form).\n if (typeof bag[locale] === 'string') return bag[locale];\n for (const [candidate, template] of Object.entries(bag)) {\n if (normalizeLocale(candidate) === locale) {\n return template;\n }\n }\n return undefined;\n}\n\nfunction finalize(args: {\n key: string;\n locale: string;\n tenantId: string | null;\n db: unknown;\n attempt: ResolutionAttempt;\n loadedAtGeneration: number;\n}): ResolutionAttempt {\n if (args.attempt.template !== null) {\n const value: LanguageCacheValue = {\n key: args.key,\n locale: args.locale,\n template: args.attempt.template,\n source: args.attempt.source,\n resolvedFromLocale: args.attempt.resolvedFromLocale,\n };\n setCachedLanguage(\n args.key,\n args.locale,\n args.tenantId,\n args.db,\n value,\n args.loadedAtGeneration,\n );\n }\n return args.attempt;\n}\n\nexport async function resolveLanguageString(\n key: string,\n options: ResolveLanguageStringOptions = {},\n): Promise<ResolvedLanguageString> {\n if (!key || key.trim() === '') {\n throw new Error('resolveLanguageString requires a non-empty key');\n }\n\n const config = getLanguagesConfig();\n const defaultLocale = normalizeLocale(config.defaultLocale ?? DEFAULT_LOCALE);\n const requested = normalizeLocale(options.locale ?? defaultLocale);\n\n // Runtime override always wins, regardless of locale chain.\n if (typeof options.overrides?.template === 'string') {\n return {\n key,\n locale: requested,\n template: options.overrides.template,\n text: renderTemplate(options.overrides.template, options.vars),\n resolvedFromLocale: requested,\n source: 'runtime',\n };\n }\n\n const chain = buildLocaleFallbackChain(requested, defaultLocale);\n\n let firstHit: ResolutionAttempt | null = null;\n let firstLocale = requested;\n for (const locale of chain) {\n const attempt = await resolveBaseForLocale(key, locale, options, config);\n if (attempt.template !== null) {\n firstHit = attempt;\n firstLocale = locale;\n break;\n }\n }\n\n if (!firstHit) {\n if (options.strict) {\n throw new Error(\n `Language string \"${key}\" has no resolution for locale \"${requested}\"`,\n );\n }\n // Soft-miss: enqueue translation if the requested locale differs from the\n // default and a default-locale source exists. Failure of the enqueue path\n // must never break resolution — we still return the key as the rendered\n // text so the UI degrades gracefully.\n await tryEnqueueTranslation({\n key,\n requestedLocale: requested,\n defaultLocale,\n options,\n });\n return {\n key,\n locale: requested,\n template: key,\n text: key,\n resolvedFromLocale: requested,\n source: 'missing',\n };\n }\n\n // Hit at a fallback locale that isn't the requested one — fire-and-forget a\n // translation job for the requested target.\n if (firstLocale !== requested) {\n await tryEnqueueTranslation({\n key,\n requestedLocale: requested,\n defaultLocale,\n options,\n });\n return {\n key,\n locale: requested,\n template: firstHit.template ?? key,\n text: renderTemplate(firstHit.template ?? key, options.vars),\n resolvedFromLocale: firstLocale,\n source: 'fallback',\n };\n }\n\n return {\n key,\n locale: requested,\n template: firstHit.template ?? key,\n text: renderTemplate(firstHit.template ?? key, options.vars),\n resolvedFromLocale: firstLocale,\n source: firstHit.source,\n };\n}\n\n/**\n * Best-effort enqueue of an AI translation job. Wrapped so resolution never\n * fails because of an enqueue error, missing optional dependency, etc.\n *\n * The actual job machinery lives in `./jobs/translation-job.ts` and is loaded\n * lazily so the resolver does not pull `@happyvertical/ai` into the import\n * graph for synchronous resolves that never miss.\n */\nasync function tryEnqueueTranslation(args: {\n key: string;\n requestedLocale: string;\n defaultLocale: string;\n options: ResolveLanguageStringOptions;\n}): Promise<void> {\n if (!args.options.db) {\n // Without a DB we cannot persist a job; skip silently — resolver still\n // returns a fallback to the caller.\n return;\n }\n if (normalizeLocale(args.requestedLocale) === args.defaultLocale) {\n return;\n }\n\n try {\n const { enqueueTranslationJob } = await import('./jobs/translation-job.js');\n await enqueueTranslationJob({\n key: args.key,\n targetLocale: args.requestedLocale,\n sourceLocale: args.defaultLocale,\n tenantId: args.options.tenantId ?? getTenantId() ?? null,\n db: args.options.db,\n });\n } catch {\n // Enqueueing must never break resolution.\n }\n}\n\nexport function invalidateResolvedLanguageCache(\n key: string,\n locale: string,\n tenantId: string | null | undefined,\n db: unknown,\n): void {\n invalidateLanguageCache(key, locale, tenantId, db);\n}\n","/**\n * @happyvertical/smrt-languages\n *\n * Code-first language strings with config + tenant overrides and AI-driven\n * auto-translation for SMRT applications. Mirrors the architecture of\n * `@happyvertical/smrt-prompts` plus a smrt-jobs handler that fills gaps in\n * non-default locales the first time a string is requested.\n *\n * The package root intentionally exposes only the read path\n * (`defineLanguageString`, `resolveLanguageString`, `LanguageOverride`, the\n * cache helpers, glossary helpers, and shared types/utilities). The\n * translation-worker stack — which depends on `@happyvertical/ai`,\n * smrt-jobs, smrt-features, and smrt-prompts — lives on the\n * `@happyvertical/smrt-languages/jobs` subpath, and the admin CLI helpers\n * live on `@happyvertical/smrt-languages/cli`. Resolver consumers (the vast\n * majority of call sites) never load the worker dependency tree.\n *\n * @packageDocumentation\n */\n\nimport './__smrt-register__.js';\n\nexport {\n clearLanguageCache,\n getLanguageCacheTtlMs,\n invalidateLanguageCache,\n} from './cache.js';\nexport { LanguageOverrideCollection } from './collections/LanguageOverrideCollection.js';\nexport { buildTenantGlossary } from './glossary.js';\n\nexport {\n defineLanguageString,\n LanguageRegistry,\n} from './language-registry.js';\n\nexport {\n invalidateResolvedLanguageCache,\n resolveLanguageString,\n} from './language-resolver.js';\n\nexport {\n LanguageOverride,\n type LanguageOverrideCtorOptions,\n} from './models/LanguageOverride.js';\n\nexport type {\n LanguageCacheValue,\n LanguageOverrideOptions,\n LanguageStringDefinition,\n LanguageStringDefinitionInput,\n LanguagesPackageConfig,\n LanguageVariables,\n ResolvedLanguageString,\n ResolveLanguageStringOptions,\n} from './types.js';\n\nexport {\n buildLocaleFallbackChain,\n buildTranslationJobId,\n computeSourceHash,\n normalizeLocale,\n renderTemplate,\n} from './utils.js';\n\n/** @internal */\nexport const PACKAGE_VERSION_INITIALIZED = true;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/__smrt-register__.ts","../src/language-resolver.ts","../src/index.ts"],"sourcesContent":["// Generated by @happyvertical/smrt-core smrtPlugin at library build time.\n// The package manifest is inlined so self-registration cannot miss when a\n// downstream bundler relocates this module away from dist/manifest.json\n// (https://github.com/happyvertical/smrt/issues/1506,\n// https://github.com/happyvertical/smrt/issues/1507).\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\nObjectRegistry.registerPackageManifest(JSON.parse(\"{\\\"version\\\":\\\"1.0.0\\\",\\\"timestamp\\\":0,\\\"packageName\\\":\\\"@happyvertical/smrt-languages\\\",\\\"packageVersion\\\":\\\"0.57.0\\\",\\\"objects\\\":{\\\"@happyvertical/smrt-languages:LanguageOverrideCollection\\\":{\\\"name\\\":\\\"languageoverridecollection\\\",\\\"className\\\":\\\"LanguageOverrideCollection\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-languages:LanguageOverrideCollection\\\",\\\"collection\\\":\\\"languageoverrides\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/languages/src/collections/LanguageOverrideCollection.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-languages\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"getAppOverride\\\":{\\\"name\\\":\\\"getAppOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"locale\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<LanguageOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getTenantOverride\\\":{\\\"name\\\":\\\"getTenantOverride\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"locale\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<LanguageOverride | null>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"getResolutionLayers\\\":{\\\"name\\\":\\\"getResolutionLayers\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"key\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"locale\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false},{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string | null\\\",\\\"optional\\\":true,\\\"unionBranches\\\":[{\\\"type\\\":\\\"string\\\"},{\\\"type\\\":\\\"null\\\"}]}],\\\"returnType\\\":\\\"Promise<object>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"listTenantOverrides\\\":{\\\"name\\\":\\\"listTenantOverrides\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"tenantId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<LanguageOverride[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"listUnreviewedAutoTranslations\\\":{\\\"name\\\":\\\"listUnreviewedAutoTranslations\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"options\\\",\\\"type\\\":\\\"object\\\",\\\"optional\\\":true,\\\"memberTypes\\\":[\\\"string\\\",\\\"number\\\"]}],\\\"returnType\\\":\\\"Promise<LanguageOverride[]>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_language_overrides\\\",\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\",\\\"delete\\\"]},\\\"mcp\\\":{\\\"include\\\":[]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\",\\\"delete\\\"],\\\"skipApiCheck\\\":true}},\\\"extends\\\":\\\"SmrtCollection\\\",\\\"extendsTypeArg\\\":\\\"LanguageOverride\\\",\\\"exportName\\\":\\\"LanguageOverrideCollection\\\",\\\"collectionExportName\\\":\\\"LanguageOverrideCollectionCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_language_overrides\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_language_overrides\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"key\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"locale\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"template\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"auto_generated\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"source_hash\\\\\\\" TEXT,\\\\n \\\\\\\"ai_model\\\\\\\" TEXT,\\\\n \\\\\\\"reviewed_at\\\\\\\" TEXT,\\\\n \\\\\\\"reviewed_by\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"locale\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"template\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"auto_generated\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"source_hash\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ai_model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"reviewed_at\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"reviewed_by\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_language_overrides_key_locale_idx\\\",\\\"columns\\\":[\\\"key\\\",\\\"locale\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_language_overrides_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_language_overrides_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"91442913\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-languages\\\"},\\\"@happyvertical/smrt-languages:LanguageTranslationTask\\\":{\\\"name\\\":\\\"languagetranslationtask\\\",\\\"className\\\":\\\"LanguageTranslationTask\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-languages:LanguageTranslationTask\\\",\\\"collection\\\":\\\"languagetranslationtasks\\\",\\\"description\\\":\\\"SmrtObject that owns the translation job's execute method. The TaskRunner resolves jobs by objectType so the registered class name needs to match what enqueueTranslationJob writes.\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/languages/src/jobs/translation-job.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-languages\\\",\\\"fields\\\":{},\\\"methods\\\":{\\\"execute\\\":{\\\"name\\\":\\\"execute\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"args\\\",\\\"type\\\":\\\"TranslationJobPayload\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<object>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"api\\\":{\\\"include\\\":[]},\\\"cli\\\":{\\\"include\\\":[]},\\\"mcp\\\":{\\\"include\\\":[]}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"LanguageTranslationTask\\\",\\\"collectionExportName\\\":\\\"LanguageTranslationTaskCollection\\\",\\\"schema\\\":{\\\"tableName\\\":\\\"language_translation_tasks\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"language_translation_tasks\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"}},\\\"indexes\\\":[{\\\"name\\\":\\\"language_translation_tasks_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"language_translation_tasks_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"2cfc8812\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-languages/jobs\\\"},\\\"@happyvertical/smrt-languages:LanguageOverride\\\":{\\\"name\\\":\\\"languageoverride\\\",\\\"className\\\":\\\"LanguageOverride\\\",\\\"qualifiedName\\\":\\\"@happyvertical/smrt-languages:LanguageOverride\\\",\\\"collection\\\":\\\"languageoverrides\\\",\\\"filePath\\\":\\\"/home/runner/work/smrt/smrt/packages/languages/src/models/LanguageOverride.ts\\\",\\\"packageName\\\":\\\"@happyvertical/smrt-languages\\\",\\\"fields\\\":{\\\"key\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"locale\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"default\\\":\\\"\\\",\\\"_meta\\\":{\\\"required\\\":true}},\\\"tenantId\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"sqlType\\\":\\\"UUID\\\",\\\"nullable\\\":true}},\\\"template\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":true,\\\"_meta\\\":{\\\"required\\\":true}},\\\"auto_generated\\\":{\\\"type\\\":\\\"boolean\\\",\\\"required\\\":true,\\\"default\\\":false,\\\"_meta\\\":{\\\"required\\\":true,\\\"default\\\":false}},\\\"source_hash\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"ai_model\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"reviewed_at\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}},\\\"reviewed_by\\\":{\\\"type\\\":\\\"text\\\",\\\"required\\\":false,\\\"_meta\\\":{\\\"nullable\\\":true}}},\\\"methods\\\":{\\\"save\\\":{\\\"name\\\":\\\"save\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"delete\\\":{\\\"name\\\":\\\"delete\\\",\\\"async\\\":true,\\\"parameters\\\":[],\\\"returnType\\\":\\\"Promise<void>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true},\\\"approve\\\":{\\\"name\\\":\\\"approve\\\",\\\"async\\\":true,\\\"parameters\\\":[{\\\"name\\\":\\\"reviewerId\\\",\\\"type\\\":\\\"string\\\",\\\"optional\\\":false}],\\\"returnType\\\":\\\"Promise<this>\\\",\\\"isStatic\\\":false,\\\"isPublic\\\":true}},\\\"decoratorConfig\\\":{\\\"tableName\\\":\\\"_smrt_language_overrides\\\",\\\"conflictColumns\\\":[\\\"key\\\",\\\"locale\\\",\\\"context\\\"],\\\"api\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\",\\\"delete\\\"]},\\\"cli\\\":{\\\"include\\\":[\\\"list\\\",\\\"get\\\",\\\"create\\\",\\\"update\\\",\\\"delete\\\",\\\"approve\\\"],\\\"skipApiCheck\\\":true},\\\"mcp\\\":{\\\"include\\\":[]}},\\\"extends\\\":\\\"SmrtObject\\\",\\\"exportName\\\":\\\"LanguageOverride\\\",\\\"collectionExportName\\\":\\\"LanguageOverrideCollection\\\",\\\"validationRules\\\":[{\\\"field\\\":\\\"key\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"locale\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"template\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"text\\\"},{\\\"field\\\":\\\"auto_generated\\\",\\\"rule\\\":\\\"required\\\",\\\"fieldType\\\":\\\"boolean\\\"}],\\\"schema\\\":{\\\"tableName\\\":\\\"_smrt_language_overrides\\\",\\\"ddl\\\":\\\"CREATE TABLE IF NOT EXISTS \\\\\\\"_smrt_language_overrides\\\\\\\" (\\\\n \\\\\\\"id\\\\\\\" UUID PRIMARY KEY NOT NULL,\\\\n \\\\\\\"slug\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"context\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"created_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"updated_at\\\\\\\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\\\\n \\\\\\\"key\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"locale\\\\\\\" TEXT NOT NULL DEFAULT '',\\\\n \\\\\\\"tenant_id\\\\\\\" UUID,\\\\n \\\\\\\"template\\\\\\\" TEXT NOT NULL,\\\\n \\\\\\\"auto_generated\\\\\\\" BOOLEAN NOT NULL DEFAULT FALSE,\\\\n \\\\\\\"source_hash\\\\\\\" TEXT,\\\\n \\\\\\\"ai_model\\\\\\\" TEXT,\\\\n \\\\\\\"reviewed_at\\\\\\\" TEXT,\\\\n \\\\\\\"reviewed_by\\\\\\\" TEXT\\\\n);\\\",\\\"columns\\\":{\\\"id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"primaryKey\\\":true,\\\"referenceKind\\\":\\\"id\\\",\\\"notNull\\\":true},\\\"slug\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true},\\\"context\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"\\\"},\\\"created_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"updated_at\\\":{\\\"type\\\":\\\"TIMESTAMP\\\",\\\"notNull\\\":true,\\\"default\\\":\\\"current_timestamp\\\"},\\\"key\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"locale\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":\\\"\\\"},\\\"tenant_id\\\":{\\\"type\\\":\\\"UUID\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"template\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":true,\\\"unique\\\":false},\\\"auto_generated\\\":{\\\"type\\\":\\\"BOOLEAN\\\",\\\"notNull\\\":true,\\\"unique\\\":false,\\\"default\\\":false},\\\"source_hash\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"ai_model\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"reviewed_at\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false},\\\"reviewed_by\\\":{\\\"type\\\":\\\"TEXT\\\",\\\"notNull\\\":false,\\\"unique\\\":false}},\\\"indexes\\\":[{\\\"name\\\":\\\"_smrt_language_overrides_key_locale_idx\\\",\\\"columns\\\":[\\\"key\\\",\\\"locale\\\",\\\"context\\\"],\\\"unique\\\":true},{\\\"name\\\":\\\"_smrt_language_overrides_slug_context_idx\\\",\\\"columns\\\":[\\\"slug\\\",\\\"context\\\"]},{\\\"name\\\":\\\"_smrt_language_overrides_created_at_idx\\\",\\\"columns\\\":[\\\"created_at\\\"]}],\\\"version\\\":\\\"91442913\\\"},\\\"importPath\\\":\\\"@happyvertical/smrt-languages\\\"}},\\\"moduleType\\\":\\\"smrt\\\",\\\"smrtDependencies\\\":[\\\"@happyvertical/smrt-core\\\",\\\"@happyvertical/smrt-features\\\",\\\"@happyvertical/smrt-jobs\\\",\\\"@happyvertical/smrt-prompts\\\",\\\"@happyvertical/smrt-tenancy\\\"],\\\"browser\\\":{\\\"status\\\":\\\"server-only\\\",\\\"issues\\\":[\\\"#3615\\\",\\\"#3618\\\",\\\"#3624\\\",\\\"#3627\\\"],\\\"reason\\\":\\\"node:crypto\\\",\\\"via\\\":[\\\"@happyvertical/smrt-features\\\",\\\"@happyvertical/smrt-jobs\\\",\\\"@happyvertical/smrt-tenancy\\\"]},\\\"stampsConstructors\\\":true}\"));\n","import { getPackageConfig } from '@happyvertical/smrt-config';\nimport { getTenantId } from '@happyvertical/smrt-tenancy';\nimport {\n getCachedLanguage,\n getLanguageCacheGeneration,\n invalidateLanguageCache,\n setCachedLanguage,\n} from './cache.js';\nimport { LanguageOverrideCollection } from './collections/LanguageOverrideCollection.js';\nimport { LanguageRegistry } from './language-registry.js';\nimport type {\n LanguageCacheValue,\n LanguagesPackageConfig,\n ResolvedLanguageString,\n ResolveLanguageStringOptions,\n} from './types.js';\nimport {\n buildLocaleFallbackChain,\n normalizeLocale,\n renderTemplate,\n} from './utils.js';\n\nconst DEFAULT_LOCALE = 'en';\n\nfunction getLanguagesConfig(): LanguagesPackageConfig {\n return getPackageConfig<LanguagesPackageConfig>('languages', {\n defaultLocale: DEFAULT_LOCALE,\n overrides: {},\n });\n}\n\ninterface ResolutionAttempt {\n template: string | null;\n source: ResolvedLanguageString['source'];\n resolvedFromLocale: string;\n}\n\nasync function resolveBaseForLocale(\n key: string,\n locale: string,\n options: ResolveLanguageStringOptions,\n config: LanguagesPackageConfig,\n): Promise<ResolutionAttempt> {\n const tenantId =\n options.tenantId !== undefined ? options.tenantId : (getTenantId() ?? null);\n\n let collection: LanguageOverrideCollection | null = null;\n if (options.db) {\n collection = await LanguageOverrideCollection.create({\n db: options.db,\n });\n }\n\n const cacheDb = collection?.db ?? options.db;\n const cached = getCachedLanguage(key, locale, tenantId, cacheDb);\n if (cached) {\n return {\n template: cached.template,\n source: cached.source,\n resolvedFromLocale: cached.resolvedFromLocale,\n };\n }\n\n // Capture the invalidation generation before the asynchronous layer loads. A\n // write that lands while they are in flight bumps it, and the cache write in\n // `finalize` is then refused rather than repopulating the entry the write\n // just invalidated with the pre-write value.\n const loadedAtGeneration = getLanguageCacheGeneration(key, locale, cacheDb);\n\n // 1. Tenant override (highest precedence among stored layers).\n if (collection && tenantId) {\n const tenantOverride = await collection.getTenantOverride(\n key,\n locale,\n tenantId,\n );\n if (tenantOverride) {\n return finalize({\n key,\n locale,\n tenantId,\n db: cacheDb,\n loadedAtGeneration,\n attempt: {\n template: tenantOverride.template,\n source: 'tenant',\n resolvedFromLocale: locale,\n },\n });\n }\n }\n\n // 2. App-level override (incl. AI auto-translations).\n if (collection) {\n const appOverride = await collection.getAppOverride(key, locale);\n if (appOverride) {\n return finalize({\n key,\n locale,\n tenantId,\n db: cacheDb,\n loadedAtGeneration,\n attempt: {\n template: appOverride.template,\n source: 'app',\n resolvedFromLocale: locale,\n },\n });\n }\n }\n\n // 3. File-config override. Locale keys in user-authored config files\n // commonly come in mixed case (`fr-ca`, `Fr-CA`, etc.); normalize lookup so\n // config matches the same way the DB and code-default layers do.\n const configForKey = config.overrides?.[key];\n const configTemplate = lookupNormalizedLocale(configForKey, locale);\n if (typeof configTemplate === 'string') {\n return finalize({\n key,\n locale,\n tenantId,\n db: cacheDb,\n loadedAtGeneration,\n attempt: {\n template: configTemplate,\n source: 'config',\n resolvedFromLocale: locale,\n },\n });\n }\n\n // 4. Code default.\n const definition = LanguageRegistry.get(key, locale);\n if (definition) {\n return finalize({\n key,\n locale,\n tenantId,\n db: cacheDb,\n loadedAtGeneration,\n attempt: {\n template: definition.template,\n source: 'code',\n resolvedFromLocale: locale,\n },\n });\n }\n\n return {\n template: null,\n source: 'missing',\n resolvedFromLocale: locale,\n };\n}\n\nfunction lookupNormalizedLocale(\n bag: Record<string, string> | undefined,\n locale: string,\n): string | undefined {\n if (!bag) return undefined;\n // Fast path: exact match (most file configs use the canonical form).\n if (typeof bag[locale] === 'string') return bag[locale];\n for (const [candidate, template] of Object.entries(bag)) {\n if (normalizeLocale(candidate) === locale) {\n return template;\n }\n }\n return undefined;\n}\n\nfunction finalize(args: {\n key: string;\n locale: string;\n tenantId: string | null;\n db: unknown;\n attempt: ResolutionAttempt;\n loadedAtGeneration: number;\n}): ResolutionAttempt {\n if (args.attempt.template !== null) {\n const value: LanguageCacheValue = {\n key: args.key,\n locale: args.locale,\n template: args.attempt.template,\n source: args.attempt.source,\n resolvedFromLocale: args.attempt.resolvedFromLocale,\n };\n setCachedLanguage(\n args.key,\n args.locale,\n args.tenantId,\n args.db,\n value,\n args.loadedAtGeneration,\n );\n }\n return args.attempt;\n}\n\nexport async function resolveLanguageString(\n key: string,\n options: ResolveLanguageStringOptions = {},\n): Promise<ResolvedLanguageString> {\n if (!key || key.trim() === '') {\n throw new Error('resolveLanguageString requires a non-empty key');\n }\n\n const config = getLanguagesConfig();\n const defaultLocale = normalizeLocale(config.defaultLocale ?? DEFAULT_LOCALE);\n const requested = normalizeLocale(options.locale ?? defaultLocale);\n\n // Runtime override always wins, regardless of locale chain.\n if (typeof options.overrides?.template === 'string') {\n return {\n key,\n locale: requested,\n template: options.overrides.template,\n text: renderTemplate(options.overrides.template, options.vars),\n resolvedFromLocale: requested,\n source: 'runtime',\n };\n }\n\n const chain = buildLocaleFallbackChain(requested, defaultLocale);\n\n let firstHit: ResolutionAttempt | null = null;\n let firstLocale = requested;\n for (const locale of chain) {\n const attempt = await resolveBaseForLocale(key, locale, options, config);\n if (attempt.template !== null) {\n firstHit = attempt;\n firstLocale = locale;\n break;\n }\n }\n\n if (!firstHit) {\n if (options.strict) {\n throw new Error(\n `Language string \"${key}\" has no resolution for locale \"${requested}\"`,\n );\n }\n // Soft-miss: enqueue translation if the requested locale differs from the\n // default and a default-locale source exists. Failure of the enqueue path\n // must never break resolution — we still return the key as the rendered\n // text so the UI degrades gracefully.\n await tryEnqueueTranslation({\n key,\n requestedLocale: requested,\n defaultLocale,\n options,\n });\n return {\n key,\n locale: requested,\n template: key,\n text: key,\n resolvedFromLocale: requested,\n source: 'missing',\n };\n }\n\n // Hit at a fallback locale that isn't the requested one — fire-and-forget a\n // translation job for the requested target.\n if (firstLocale !== requested) {\n await tryEnqueueTranslation({\n key,\n requestedLocale: requested,\n defaultLocale,\n options,\n });\n return {\n key,\n locale: requested,\n template: firstHit.template ?? key,\n text: renderTemplate(firstHit.template ?? key, options.vars),\n resolvedFromLocale: firstLocale,\n source: 'fallback',\n };\n }\n\n return {\n key,\n locale: requested,\n template: firstHit.template ?? key,\n text: renderTemplate(firstHit.template ?? key, options.vars),\n resolvedFromLocale: firstLocale,\n source: firstHit.source,\n };\n}\n\n/**\n * Best-effort enqueue of an AI translation job. Wrapped so resolution never\n * fails because of an enqueue error, missing optional dependency, etc.\n *\n * The actual job machinery lives in `./jobs/translation-job.ts` and is loaded\n * lazily so the resolver does not pull `@happyvertical/ai` into the import\n * graph for synchronous resolves that never miss.\n */\nasync function tryEnqueueTranslation(args: {\n key: string;\n requestedLocale: string;\n defaultLocale: string;\n options: ResolveLanguageStringOptions;\n}): Promise<void> {\n if (!args.options.db) {\n // Without a DB we cannot persist a job; skip silently — resolver still\n // returns a fallback to the caller.\n return;\n }\n if (normalizeLocale(args.requestedLocale) === args.defaultLocale) {\n return;\n }\n\n try {\n const { enqueueTranslationJob } = await import('./jobs/translation-job.js');\n await enqueueTranslationJob({\n key: args.key,\n targetLocale: args.requestedLocale,\n sourceLocale: args.defaultLocale,\n tenantId: args.options.tenantId ?? getTenantId() ?? null,\n db: args.options.db,\n });\n } catch {\n // Enqueueing must never break resolution.\n }\n}\n\nexport function invalidateResolvedLanguageCache(\n key: string,\n locale: string,\n tenantId: string | null | undefined,\n db: unknown,\n): void {\n invalidateLanguageCache(key, locale, tenantId, db);\n}\n","/**\n * @happyvertical/smrt-languages\n *\n * Code-first language strings with config + tenant overrides and AI-driven\n * auto-translation for SMRT applications. Mirrors the architecture of\n * `@happyvertical/smrt-prompts` plus a smrt-jobs handler that fills gaps in\n * non-default locales the first time a string is requested.\n *\n * The package root intentionally exposes only the read path\n * (`defineLanguageString`, `resolveLanguageString`, `LanguageOverride`, the\n * cache helpers, glossary helpers, and shared types/utilities). The\n * translation-worker stack — which depends on `@happyvertical/ai`,\n * smrt-jobs, smrt-features, and smrt-prompts — lives on the\n * `@happyvertical/smrt-languages/jobs` subpath, and the admin CLI helpers\n * live on `@happyvertical/smrt-languages/cli`. Resolver consumers (the vast\n * majority of call sites) never load the worker dependency tree.\n *\n * @packageDocumentation\n */\n\nimport './__smrt-register__.js';\n\nexport {\n clearLanguageCache,\n getLanguageCacheTtlMs,\n invalidateLanguageCache,\n} from './cache.js';\nexport { LanguageOverrideCollection } from './collections/LanguageOverrideCollection.js';\nexport { buildTenantGlossary } from './glossary.js';\n\nexport {\n defineLanguageString,\n LanguageRegistry,\n} from './language-registry.js';\n\nexport {\n invalidateResolvedLanguageCache,\n resolveLanguageString,\n} from './language-resolver.js';\n\nexport {\n LanguageOverride,\n type LanguageOverrideCtorOptions,\n} from './models/LanguageOverride.js';\n\nexport type {\n LanguageCacheValue,\n LanguageOverrideOptions,\n LanguageStringDefinition,\n LanguageStringDefinitionInput,\n LanguagesPackageConfig,\n LanguageVariables,\n ResolvedLanguageString,\n ResolveLanguageStringOptions,\n} from './types.js';\n\nexport {\n buildLocaleFallbackChain,\n buildTranslationJobId,\n computeSourceHash,\n normalizeLocale,\n renderTemplate,\n} from './utils.js';\n\n/** @internal */\nexport const PACKAGE_VERSION_INITIALIZED = true;\n"],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  "version": "1.0.0",
3
3
  "timestamp": 0,
4
4
  "packageName": "@happyvertical/smrt-languages",
5
- "packageVersion": "0.56.1",
5
+ "packageVersion": "0.57.0",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-languages:LanguageOverrideCollection": {
8
8
  "name": "languageoverridecollection",
@@ -122,7 +122,29 @@
122
122
  }
123
123
  },
124
124
  "decoratorConfig": {
125
- "tableName": "_smrt_language_overrides"
125
+ "tableName": "_smrt_language_overrides",
126
+ "api": {
127
+ "include": [
128
+ "list",
129
+ "get",
130
+ "create",
131
+ "update",
132
+ "delete"
133
+ ]
134
+ },
135
+ "mcp": {
136
+ "include": []
137
+ },
138
+ "cli": {
139
+ "include": [
140
+ "list",
141
+ "get",
142
+ "create",
143
+ "update",
144
+ "delete"
145
+ ],
146
+ "skipApiCheck": true
147
+ }
126
148
  },
127
149
  "extends": "SmrtCollection",
128
150
  "extendsTypeArg": "LanguageOverride",
@@ -234,6 +256,95 @@
234
256
  },
235
257
  "importPath": "@happyvertical/smrt-languages"
236
258
  },
259
+ "@happyvertical/smrt-languages:LanguageTranslationTask": {
260
+ "name": "languagetranslationtask",
261
+ "className": "LanguageTranslationTask",
262
+ "qualifiedName": "@happyvertical/smrt-languages:LanguageTranslationTask",
263
+ "collection": "languagetranslationtasks",
264
+ "description": "SmrtObject that owns the translation job's execute method. The TaskRunner resolves jobs by objectType so the registered class name needs to match what enqueueTranslationJob writes.",
265
+ "filePath": "/home/runner/work/smrt/smrt/packages/languages/src/jobs/translation-job.ts",
266
+ "packageName": "@happyvertical/smrt-languages",
267
+ "fields": {},
268
+ "methods": {
269
+ "execute": {
270
+ "name": "execute",
271
+ "async": true,
272
+ "parameters": [
273
+ {
274
+ "name": "args",
275
+ "type": "TranslationJobPayload",
276
+ "optional": false
277
+ }
278
+ ],
279
+ "returnType": "Promise<object>",
280
+ "isStatic": false,
281
+ "isPublic": true
282
+ }
283
+ },
284
+ "decoratorConfig": {
285
+ "api": {
286
+ "include": []
287
+ },
288
+ "cli": {
289
+ "include": []
290
+ },
291
+ "mcp": {
292
+ "include": []
293
+ }
294
+ },
295
+ "extends": "SmrtObject",
296
+ "exportName": "LanguageTranslationTask",
297
+ "collectionExportName": "LanguageTranslationTaskCollection",
298
+ "schema": {
299
+ "tableName": "language_translation_tasks",
300
+ "ddl": "CREATE TABLE IF NOT EXISTS \"language_translation_tasks\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp\n);",
301
+ "columns": {
302
+ "id": {
303
+ "type": "UUID",
304
+ "primaryKey": true,
305
+ "referenceKind": "id",
306
+ "notNull": true
307
+ },
308
+ "slug": {
309
+ "type": "TEXT",
310
+ "notNull": true
311
+ },
312
+ "context": {
313
+ "type": "TEXT",
314
+ "notNull": true,
315
+ "default": ""
316
+ },
317
+ "created_at": {
318
+ "type": "TIMESTAMP",
319
+ "notNull": true,
320
+ "default": "current_timestamp"
321
+ },
322
+ "updated_at": {
323
+ "type": "TIMESTAMP",
324
+ "notNull": true,
325
+ "default": "current_timestamp"
326
+ }
327
+ },
328
+ "indexes": [
329
+ {
330
+ "name": "language_translation_tasks_slug_context_idx",
331
+ "columns": [
332
+ "slug",
333
+ "context"
334
+ ],
335
+ "unique": true
336
+ },
337
+ {
338
+ "name": "language_translation_tasks_created_at_idx",
339
+ "columns": [
340
+ "created_at"
341
+ ]
342
+ }
343
+ ],
344
+ "version": "2cfc8812"
345
+ },
346
+ "importPath": "@happyvertical/smrt-languages/jobs"
347
+ },
237
348
  "@happyvertical/smrt-languages:LanguageOverride": {
238
349
  "name": "languageoverride",
239
350
  "className": "LanguageOverride",
@@ -504,95 +615,6 @@
504
615
  "version": "91442913"
505
616
  },
506
617
  "importPath": "@happyvertical/smrt-languages"
507
- },
508
- "@happyvertical/smrt-languages:LanguageTranslationTask": {
509
- "name": "languagetranslationtask",
510
- "className": "LanguageTranslationTask",
511
- "qualifiedName": "@happyvertical/smrt-languages:LanguageTranslationTask",
512
- "collection": "languagetranslationtasks",
513
- "description": "SmrtObject that owns the translation job's execute method. The TaskRunner resolves jobs by objectType so the registered class name needs to match what enqueueTranslationJob writes.",
514
- "filePath": "/home/runner/work/smrt/smrt/packages/languages/src/jobs/translation-job.ts",
515
- "packageName": "@happyvertical/smrt-languages",
516
- "fields": {},
517
- "methods": {
518
- "execute": {
519
- "name": "execute",
520
- "async": true,
521
- "parameters": [
522
- {
523
- "name": "args",
524
- "type": "TranslationJobPayload",
525
- "optional": false
526
- }
527
- ],
528
- "returnType": "Promise<object>",
529
- "isStatic": false,
530
- "isPublic": true
531
- }
532
- },
533
- "decoratorConfig": {
534
- "api": {
535
- "include": []
536
- },
537
- "cli": {
538
- "include": []
539
- },
540
- "mcp": {
541
- "include": []
542
- }
543
- },
544
- "extends": "SmrtObject",
545
- "exportName": "LanguageTranslationTask",
546
- "collectionExportName": "LanguageTranslationTaskCollection",
547
- "schema": {
548
- "tableName": "language_translation_tasks",
549
- "ddl": "CREATE TABLE IF NOT EXISTS \"language_translation_tasks\" (\n \"id\" UUID PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp\n);",
550
- "columns": {
551
- "id": {
552
- "type": "UUID",
553
- "primaryKey": true,
554
- "referenceKind": "id",
555
- "notNull": true
556
- },
557
- "slug": {
558
- "type": "TEXT",
559
- "notNull": true
560
- },
561
- "context": {
562
- "type": "TEXT",
563
- "notNull": true,
564
- "default": ""
565
- },
566
- "created_at": {
567
- "type": "TIMESTAMP",
568
- "notNull": true,
569
- "default": "current_timestamp"
570
- },
571
- "updated_at": {
572
- "type": "TIMESTAMP",
573
- "notNull": true,
574
- "default": "current_timestamp"
575
- }
576
- },
577
- "indexes": [
578
- {
579
- "name": "language_translation_tasks_slug_context_idx",
580
- "columns": [
581
- "slug",
582
- "context"
583
- ],
584
- "unique": true
585
- },
586
- {
587
- "name": "language_translation_tasks_created_at_idx",
588
- "columns": [
589
- "created_at"
590
- ]
591
- }
592
- ],
593
- "version": "2cfc8812"
594
- },
595
- "importPath": "@happyvertical/smrt-languages/jobs"
596
618
  }
597
619
  },
598
620
  "moduleType": "smrt",
@@ -3,12 +3,12 @@
3
3
  "sensitiveFieldsExcluded": true,
4
4
  "generatedAt": "1970-01-01T00:00:00.000Z",
5
5
  "packageName": "@happyvertical/smrt-languages",
6
- "packageVersion": "0.56.1",
6
+ "packageVersion": "0.57.0",
7
7
  "sourceManifestPath": "dist/manifest.json",
8
8
  "agentDocPath": "AGENTS.md",
9
9
  "sourceHashes": {
10
- "manifest": "f001664678f7785aa0ae5f6cd920a4bb7348f0be72a858dc7e7e34cb489ab3ae",
11
- "packageJson": "2e6a5d2c0e54719becfc9b409054bb5837dcc25ba142721131e9c698d2f846f2",
10
+ "manifest": "a383200230dd0cb9e6e5cd21394d1c79b96f516b67b82b83b3b9b2677cb72a74",
11
+ "packageJson": "0096d755ee303f763969b3d5b53432ebf368b71a09ec9c4947e2abefae35ef47",
12
12
  "agents": "45d290839ba542a82a3cdf421d919a9dbc31f5280823ac432662bd678a087d7a"
13
13
  },
14
14
  "exports": [
@@ -126,106 +126,81 @@
126
126
  "returns": "Promise<LanguageOverride[]>"
127
127
  }
128
128
  ],
129
- "surfaces": [
129
+ "surfaces": [],
130
+ "withheldSurfaces": [
130
131
  {
131
132
  "kind": "api",
132
- "name": "languageoverrides.getAppOverride",
133
133
  "operation": "getAppOverride",
134
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
135
- "path": "/languageoverrides/getAppOverride",
136
- "method": "POST"
137
- },
138
- {
139
- "kind": "api",
140
- "name": "languageoverrides.getTenantOverride",
141
- "operation": "getTenantOverride",
142
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
143
- "path": "/languageoverrides/getTenantOverride",
144
- "method": "POST"
134
+ "code": "not-included",
135
+ "reason": "not listed in api.include",
136
+ "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
145
137
  },
146
138
  {
147
139
  "kind": "api",
148
- "name": "languageoverrides.getResolutionLayers",
149
140
  "operation": "getResolutionLayers",
150
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
151
- "path": "/languageoverrides/getResolutionLayers",
152
- "method": "POST"
153
- },
154
- {
155
- "kind": "api",
156
- "name": "languageoverrides.listTenantOverrides",
157
- "operation": "listTenantOverrides",
158
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
159
- "path": "/languageoverrides/listTenantOverrides",
160
- "method": "POST"
161
- },
162
- {
163
- "kind": "api",
164
- "name": "languageoverrides.listUnreviewedAutoTranslations",
165
- "operation": "listUnreviewedAutoTranslations",
166
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
167
- "path": "/languageoverrides/listUnreviewedAutoTranslations",
168
- "method": "POST"
169
- },
170
- {
171
- "kind": "cli",
172
- "name": "languageoverridecollection_getAppOverride",
173
- "operation": "getAppOverride",
141
+ "code": "not-included",
142
+ "reason": "not listed in api.include",
174
143
  "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
175
144
  },
176
145
  {
177
- "kind": "cli",
178
- "name": "languageoverridecollection_getTenantOverride",
146
+ "kind": "api",
179
147
  "operation": "getTenantOverride",
148
+ "code": "not-included",
149
+ "reason": "not listed in api.include",
180
150
  "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
181
151
  },
182
152
  {
183
- "kind": "cli",
184
- "name": "languageoverridecollection_getResolutionLayers",
185
- "operation": "getResolutionLayers",
186
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
187
- },
188
- {
189
- "kind": "cli",
190
- "name": "languageoverridecollection_listTenantOverrides",
153
+ "kind": "api",
191
154
  "operation": "listTenantOverrides",
155
+ "code": "not-included",
156
+ "reason": "not listed in api.include",
192
157
  "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
193
158
  },
194
159
  {
195
- "kind": "cli",
196
- "name": "languageoverridecollection_listUnreviewedAutoTranslations",
160
+ "kind": "api",
197
161
  "operation": "listUnreviewedAutoTranslations",
162
+ "code": "not-included",
163
+ "reason": "not listed in api.include",
198
164
  "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
199
- },
200
- {
201
- "kind": "mcp",
202
- "name": "languageoverridecollection_getappoverride",
203
- "operation": "getAppOverride",
204
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
205
- },
206
- {
207
- "kind": "mcp",
208
- "name": "languageoverridecollection_gettenantoverride",
209
- "operation": "getTenantOverride",
210
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
211
- },
212
- {
213
- "kind": "mcp",
214
- "name": "languageoverridecollection_getresolutionlayers",
215
- "operation": "getResolutionLayers",
216
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
217
- },
165
+ }
166
+ ],
167
+ "relationshipFeatures": [
168
+ "uuidColumns"
169
+ ],
170
+ "tags": [],
171
+ "risks": []
172
+ },
173
+ {
174
+ "name": "LanguageTranslationTask",
175
+ "qualifiedName": "@happyvertical/smrt-languages:LanguageTranslationTask",
176
+ "collection": "languagetranslationtasks",
177
+ "description": "SmrtObject that owns the translation job's execute method. The TaskRunner resolves jobs by objectType so the registered class name needs to match what enqueueTranslationJob writes.",
178
+ "tableName": "language_translation_tasks",
179
+ "packageName": "@happyvertical/smrt-languages",
180
+ "extends": "SmrtObject",
181
+ "fields": [],
182
+ "relationships": [],
183
+ "methods": [
184
+ "execute"
185
+ ],
186
+ "methodSignatures": [
218
187
  {
219
- "kind": "mcp",
220
- "name": "languageoverridecollection_listtenantoverrides",
221
- "operation": "listTenantOverrides",
222
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
223
- },
188
+ "name": "execute",
189
+ "async": true,
190
+ "params": [
191
+ "args: TranslationJobPayload"
192
+ ],
193
+ "returns": "Promise<object>"
194
+ }
195
+ ],
196
+ "surfaces": [],
197
+ "withheldSurfaces": [
224
198
  {
225
- "kind": "mcp",
226
- "name": "languageoverridecollection_listunreviewedautotranslations",
227
- "operation": "listUnreviewedAutoTranslations",
228
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
199
+ "kind": "api",
200
+ "operation": "execute",
201
+ "code": "not-included",
202
+ "reason": "not listed in api.include",
203
+ "objectName": "@happyvertical/smrt-languages:LanguageTranslationTask"
229
204
  }
230
205
  ],
231
206
  "relationshipFeatures": [
@@ -430,148 +405,9 @@
430
405
  ],
431
406
  "tags": [],
432
407
  "risks": []
433
- },
434
- {
435
- "name": "LanguageTranslationTask",
436
- "qualifiedName": "@happyvertical/smrt-languages:LanguageTranslationTask",
437
- "collection": "languagetranslationtasks",
438
- "description": "SmrtObject that owns the translation job's execute method. The TaskRunner resolves jobs by objectType so the registered class name needs to match what enqueueTranslationJob writes.",
439
- "tableName": "language_translation_tasks",
440
- "packageName": "@happyvertical/smrt-languages",
441
- "extends": "SmrtObject",
442
- "fields": [],
443
- "relationships": [],
444
- "methods": [
445
- "execute"
446
- ],
447
- "methodSignatures": [
448
- {
449
- "name": "execute",
450
- "async": true,
451
- "params": [
452
- "args: TranslationJobPayload"
453
- ],
454
- "returns": "Promise<object>"
455
- }
456
- ],
457
- "surfaces": [],
458
- "withheldSurfaces": [
459
- {
460
- "kind": "api",
461
- "operation": "execute",
462
- "code": "not-included",
463
- "reason": "not listed in api.include",
464
- "objectName": "@happyvertical/smrt-languages:LanguageTranslationTask"
465
- }
466
- ],
467
- "relationshipFeatures": [
468
- "uuidColumns"
469
- ],
470
- "tags": [],
471
- "risks": []
472
408
  }
473
409
  ],
474
410
  "surfaces": [
475
- {
476
- "kind": "api",
477
- "name": "languageoverrides.getAppOverride",
478
- "operation": "getAppOverride",
479
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
480
- "path": "/languageoverrides/getAppOverride",
481
- "method": "POST"
482
- },
483
- {
484
- "kind": "api",
485
- "name": "languageoverrides.getTenantOverride",
486
- "operation": "getTenantOverride",
487
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
488
- "path": "/languageoverrides/getTenantOverride",
489
- "method": "POST"
490
- },
491
- {
492
- "kind": "api",
493
- "name": "languageoverrides.getResolutionLayers",
494
- "operation": "getResolutionLayers",
495
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
496
- "path": "/languageoverrides/getResolutionLayers",
497
- "method": "POST"
498
- },
499
- {
500
- "kind": "api",
501
- "name": "languageoverrides.listTenantOverrides",
502
- "operation": "listTenantOverrides",
503
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
504
- "path": "/languageoverrides/listTenantOverrides",
505
- "method": "POST"
506
- },
507
- {
508
- "kind": "api",
509
- "name": "languageoverrides.listUnreviewedAutoTranslations",
510
- "operation": "listUnreviewedAutoTranslations",
511
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection",
512
- "path": "/languageoverrides/listUnreviewedAutoTranslations",
513
- "method": "POST"
514
- },
515
- {
516
- "kind": "cli",
517
- "name": "languageoverridecollection_getAppOverride",
518
- "operation": "getAppOverride",
519
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
520
- },
521
- {
522
- "kind": "cli",
523
- "name": "languageoverridecollection_getTenantOverride",
524
- "operation": "getTenantOverride",
525
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
526
- },
527
- {
528
- "kind": "cli",
529
- "name": "languageoverridecollection_getResolutionLayers",
530
- "operation": "getResolutionLayers",
531
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
532
- },
533
- {
534
- "kind": "cli",
535
- "name": "languageoverridecollection_listTenantOverrides",
536
- "operation": "listTenantOverrides",
537
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
538
- },
539
- {
540
- "kind": "cli",
541
- "name": "languageoverridecollection_listUnreviewedAutoTranslations",
542
- "operation": "listUnreviewedAutoTranslations",
543
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
544
- },
545
- {
546
- "kind": "mcp",
547
- "name": "languageoverridecollection_getappoverride",
548
- "operation": "getAppOverride",
549
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
550
- },
551
- {
552
- "kind": "mcp",
553
- "name": "languageoverridecollection_gettenantoverride",
554
- "operation": "getTenantOverride",
555
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
556
- },
557
- {
558
- "kind": "mcp",
559
- "name": "languageoverridecollection_getresolutionlayers",
560
- "operation": "getResolutionLayers",
561
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
562
- },
563
- {
564
- "kind": "mcp",
565
- "name": "languageoverridecollection_listtenantoverrides",
566
- "operation": "listTenantOverrides",
567
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
568
- },
569
- {
570
- "kind": "mcp",
571
- "name": "languageoverridecollection_listunreviewedautotranslations",
572
- "operation": "listUnreviewedAutoTranslations",
573
- "objectName": "@happyvertical/smrt-languages:LanguageOverrideCollection"
574
- },
575
411
  {
576
412
  "kind": "api",
577
413
  "name": "languageoverrides.list",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-languages",
3
- "version": "0.56.1",
3
+ "version": "0.57.0",
4
4
  "description": "Code-first language strings with config + tenant overrides and AI auto-translation for SMRT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -29,17 +29,17 @@
29
29
  "dependencies": {
30
30
  "@happyvertical/ai": "^0.103.7",
31
31
  "@happyvertical/logger": "^0.103.7",
32
- "@happyvertical/smrt-config": "0.56.1",
33
- "@happyvertical/smrt-core": "0.56.1",
34
- "@happyvertical/smrt-features": "0.56.1",
35
- "@happyvertical/smrt-jobs": "0.56.1",
36
- "@happyvertical/smrt-prompts": "0.56.1",
37
- "@happyvertical/smrt-tenancy": "0.56.1",
32
+ "@happyvertical/smrt-config": "0.57.0",
33
+ "@happyvertical/smrt-core": "0.57.0",
34
+ "@happyvertical/smrt-features": "0.57.0",
35
+ "@happyvertical/smrt-jobs": "0.57.0",
36
+ "@happyvertical/smrt-prompts": "0.57.0",
37
+ "@happyvertical/smrt-tenancy": "0.57.0",
38
38
  "@happyvertical/sql": "^0.103.7"
39
39
  },
40
40
  "devDependencies": {
41
- "@happyvertical/smrt-cli": "0.56.1",
42
- "@happyvertical/smrt-vitest": "0.56.1",
41
+ "@happyvertical/smrt-cli": "0.57.0",
42
+ "@happyvertical/smrt-vitest": "0.57.0",
43
43
  "@types/node": "24.13.6",
44
44
  "typescript": "6.0.3",
45
45
  "vite": "8.1.4",