@happyvertical/smrt-languages 0.55.7 → 0.55.9
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 +1 -1
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +16 -1
- package/dist/smrt-knowledge.json +19 -4
- package/package.json +12 -12
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.55.7","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: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"],"stampsConstructors":true}`));
|
|
6
|
+
ObjectRegistry.registerPackageManifest(JSON.parse(`{"version":"1.0.0","timestamp":0,"packageName":"@happyvertical/smrt-languages","packageVersion":"0.55.9","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: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.55.7\\\",\\\"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: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\\\"],\\\"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.55.9\\\",\\\"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: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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"}
|
package/dist/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": "1.0.0",
|
|
3
3
|
"timestamp": 0,
|
|
4
4
|
"packageName": "@happyvertical/smrt-languages",
|
|
5
|
-
"packageVersion": "0.55.
|
|
5
|
+
"packageVersion": "0.55.9",
|
|
6
6
|
"objects": {
|
|
7
7
|
"@happyvertical/smrt-languages:LanguageOverrideCollection": {
|
|
8
8
|
"name": "languageoverridecollection",
|
|
@@ -603,5 +603,20 @@
|
|
|
603
603
|
"@happyvertical/smrt-prompts",
|
|
604
604
|
"@happyvertical/smrt-tenancy"
|
|
605
605
|
],
|
|
606
|
+
"browser": {
|
|
607
|
+
"status": "server-only",
|
|
608
|
+
"issues": [
|
|
609
|
+
"#3615",
|
|
610
|
+
"#3618",
|
|
611
|
+
"#3624",
|
|
612
|
+
"#3627"
|
|
613
|
+
],
|
|
614
|
+
"reason": "node:crypto",
|
|
615
|
+
"via": [
|
|
616
|
+
"@happyvertical/smrt-features",
|
|
617
|
+
"@happyvertical/smrt-jobs",
|
|
618
|
+
"@happyvertical/smrt-tenancy"
|
|
619
|
+
]
|
|
620
|
+
},
|
|
606
621
|
"stampsConstructors": true
|
|
607
622
|
}
|
package/dist/smrt-knowledge.json
CHANGED
|
@@ -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.55.
|
|
6
|
+
"packageVersion": "0.55.9",
|
|
7
7
|
"sourceManifestPath": "dist/manifest.json",
|
|
8
8
|
"agentDocPath": "AGENTS.md",
|
|
9
9
|
"sourceHashes": {
|
|
10
|
-
"manifest": "
|
|
11
|
-
"packageJson": "
|
|
10
|
+
"manifest": "c9d70cc4b54242c2e8f3320c67d438e4cdf731c548ea0ae2fb37c64b66e321ae",
|
|
11
|
+
"packageJson": "0d0d8fe2c6e35364795954eeac26a84993bb7cd7670212260ac8b32ed3d00bd8",
|
|
12
12
|
"agents": "45d290839ba542a82a3cdf421d919a9dbc31f5280823ac432662bd678a087d7a"
|
|
13
13
|
},
|
|
14
14
|
"exports": [
|
|
@@ -662,5 +662,20 @@
|
|
|
662
662
|
"polymorphicAssociations": 0,
|
|
663
663
|
"uuidColumns": 5
|
|
664
664
|
},
|
|
665
|
-
"agentDoc": "# languages\n\nSMRT language string registry with file/config + tenant overrides and AI-driven\nauto-translation for missing locales.\n\n## Core pieces\n\n- `defineLanguageString({ key, locale, template })` registers a code default in\n a global process registry. Same shape as `definePrompt` but keyed by\n `(key, locale)` rather than `key` alone.\n- `resolveLanguageString(key, options)` walks the 5-layer chain (code → file\n config → app override → tenant override → runtime override) and falls back\n through the locale chain (`fr-CA` → `fr` → default) before giving up.\n- `LanguageOverride` stores app-level and tenant-level overrides in\n `_smrt_language_overrides`. `auto_generated`, `source_hash`, `ai_model`,\n `reviewed_at`, `reviewed_by` fields support the AI auto-translation pipeline\n and admin review queue.\n- `enqueueTranslationJob({ key, targetLocale })` writes a `LanguageTranslationTask`\n job into the `languages` queue with a deterministic dedup ID so concurrent\n resolver misses collapse into one job.\n- Keep `LanguageTranslationTask` under `src/jobs/`: the manifest generator uses\n that path to stamp its `@happyvertical/smrt-languages/jobs` import path. The\n package root intentionally excludes the translation-worker dependency tree.\n\n## Locale-miss flow\n\nWhen `resolveLanguageString` cannot find an exact `(key, locale, tenantId)`:\n\n1. Walk the locale fallback chain (`buildLocaleFallbackChain`).\n2. Return the first hit — same call returns immediately with\n `source: 'fallback'`.\n3. Fire-and-forget `enqueueTranslationJob` for the missing target, scoped to\n the current tenant for glossary purposes. App-level translations are\n reusable across tenants, so the resulting `LanguageOverride` row is written\n with `tenantId: null`.\n4. Subsequent requests hit the new app-level row and resolve at the requested\n locale.\n\nThe translation job:\n\n- Honors the `smrt-languages.auto_translate` feature flag (kill switch).\n- Skips locales outside `supportedLocales` when configured.\n- Skips when `LanguageOverride` already exists with a matching `source_hash`\n (re-translation is hash-gated, never time-based).\n- Never overwrites a row with `auto_generated: false` — human edits win\n permanently.\n- Pulls the tenant's existing overrides and renders them as a glossary so\n auto-translations match tenant voice.\n\n## Conventions\n\n- Keys are namespaced by package: `users.role.member`, `commerce.invoice.dueText`.\n- Locales follow BCP-47 (`en`, `fr-CA`, `pt-BR`) and are normalized to\n lowercase-language / uppercase-region on persistence.\n- The translation prompt itself is registered with `smrt-prompts` under\n `smrt-languages.translation` so ops can tune wording without redeploying.\n- `context` column on `_smrt_language_overrides` is set to `tenantId` or\n `'__app__'` so the `(key, locale, context)` upsert key remains unique even\n with nullable `tenantId`.\n\n## Caching\n\n`resolveLanguageString()` results are cached per `(db, key, locale, tenantId)`\nwith a TTL, invalidated on `LanguageOverride.save()` / `.delete()` (both\nidentities when one changes) and by the translation job. An app-level write\n(`tenantId = null`) clears every tenant's entry for that `(key, locale)`. Use\n`clearLanguageCache()` in tests.\n\n**A monotonic per-`(db, key, locale)` invalidation generation guards the cache\nwrite.** A resolution captures `getLanguageCacheGeneration(key, locale, db)`\nbefore its asynchronous layer loads and hands it back to `setCachedLanguage()`;\na concurrent write bumps the generation and the in-flight resolution is then\nrefused the cache write instead of repopulating the entry it just invalidated\nwith the pre-write value. Without it, a read that raced a write served the\npre-write value for the full 30s TTL, and a raced `delete()` resurrected the\ndeleted override. The generation includes `locale` — unlike `smrt-playbooks`\nand `smrt-prompts`, which have no locale dimension — because every layer a\ncached entry is built from is read at exactly the locale it is cached under:\nthe fallback chain (`fr-CA` → `fr` → `en`) resolves each locale independently\nand an attempt that resolves nothing caches nothing, so a fallback hit is never\nstored under the requested locale. It deliberately excludes `tenantId`, because\nan app-level row is inherited by every tenant. `clearLanguageCache()` raises a\nsingle floor (`clearedThrough`) rather than resetting or per-entry bumping: a\n`(key, locale)` that has never been invalidated has no map entry and reads as\ngeneration 0, so a per-entry bump cannot reach it and a resolution that started\nbefore the clear would write its pre-clear value back.\n\n## Public API surface\n\n```typescript\nimport {\n defineLanguageString,\n resolveLanguageString,\n LanguageOverride,\n LanguageOverrideCollection,\n clearLanguageCache,\n} from '@happyvertical/smrt-languages';\n\ndefineLanguageString({\n key: 'users.role.member',\n locale: 'en',\n template: 'Member',\n});\n\nconst text = await resolveLanguageString('users.role.member', {\n db,\n tenantId: 'tenant-a',\n locale: 'es',\n vars: { name: 'Will' },\n});\n```\n"
|
|
665
|
+
"agentDoc": "# languages\n\nSMRT language string registry with file/config + tenant overrides and AI-driven\nauto-translation for missing locales.\n\n## Core pieces\n\n- `defineLanguageString({ key, locale, template })` registers a code default in\n a global process registry. Same shape as `definePrompt` but keyed by\n `(key, locale)` rather than `key` alone.\n- `resolveLanguageString(key, options)` walks the 5-layer chain (code → file\n config → app override → tenant override → runtime override) and falls back\n through the locale chain (`fr-CA` → `fr` → default) before giving up.\n- `LanguageOverride` stores app-level and tenant-level overrides in\n `_smrt_language_overrides`. `auto_generated`, `source_hash`, `ai_model`,\n `reviewed_at`, `reviewed_by` fields support the AI auto-translation pipeline\n and admin review queue.\n- `enqueueTranslationJob({ key, targetLocale })` writes a `LanguageTranslationTask`\n job into the `languages` queue with a deterministic dedup ID so concurrent\n resolver misses collapse into one job.\n- Keep `LanguageTranslationTask` under `src/jobs/`: the manifest generator uses\n that path to stamp its `@happyvertical/smrt-languages/jobs` import path. The\n package root intentionally excludes the translation-worker dependency tree.\n\n## Locale-miss flow\n\nWhen `resolveLanguageString` cannot find an exact `(key, locale, tenantId)`:\n\n1. Walk the locale fallback chain (`buildLocaleFallbackChain`).\n2. Return the first hit — same call returns immediately with\n `source: 'fallback'`.\n3. Fire-and-forget `enqueueTranslationJob` for the missing target, scoped to\n the current tenant for glossary purposes. App-level translations are\n reusable across tenants, so the resulting `LanguageOverride` row is written\n with `tenantId: null`.\n4. Subsequent requests hit the new app-level row and resolve at the requested\n locale.\n\nThe translation job:\n\n- Honors the `smrt-languages.auto_translate` feature flag (kill switch).\n- Skips locales outside `supportedLocales` when configured.\n- Skips when `LanguageOverride` already exists with a matching `source_hash`\n (re-translation is hash-gated, never time-based).\n- Never overwrites a row with `auto_generated: false` — human edits win\n permanently.\n- Pulls the tenant's existing overrides and renders them as a glossary so\n auto-translations match tenant voice.\n\n## Conventions\n\n- Keys are namespaced by package: `users.role.member`, `commerce.invoice.dueText`.\n- Locales follow BCP-47 (`en`, `fr-CA`, `pt-BR`) and are normalized to\n lowercase-language / uppercase-region on persistence.\n- The translation prompt itself is registered with `smrt-prompts` under\n `smrt-languages.translation` so ops can tune wording without redeploying.\n- `context` column on `_smrt_language_overrides` is set to `tenantId` or\n `'__app__'` so the `(key, locale, context)` upsert key remains unique even\n with nullable `tenantId`.\n\n## Caching\n\n`resolveLanguageString()` results are cached per `(db, key, locale, tenantId)`\nwith a TTL, invalidated on `LanguageOverride.save()` / `.delete()` (both\nidentities when one changes) and by the translation job. An app-level write\n(`tenantId = null`) clears every tenant's entry for that `(key, locale)`. Use\n`clearLanguageCache()` in tests.\n\n**A monotonic per-`(db, key, locale)` invalidation generation guards the cache\nwrite.** A resolution captures `getLanguageCacheGeneration(key, locale, db)`\nbefore its asynchronous layer loads and hands it back to `setCachedLanguage()`;\na concurrent write bumps the generation and the in-flight resolution is then\nrefused the cache write instead of repopulating the entry it just invalidated\nwith the pre-write value. Without it, a read that raced a write served the\npre-write value for the full 30s TTL, and a raced `delete()` resurrected the\ndeleted override. The generation includes `locale` — unlike `smrt-playbooks`\nand `smrt-prompts`, which have no locale dimension — because every layer a\ncached entry is built from is read at exactly the locale it is cached under:\nthe fallback chain (`fr-CA` → `fr` → `en`) resolves each locale independently\nand an attempt that resolves nothing caches nothing, so a fallback hit is never\nstored under the requested locale. It deliberately excludes `tenantId`, because\nan app-level row is inherited by every tenant. `clearLanguageCache()` raises a\nsingle floor (`clearedThrough`) rather than resetting or per-entry bumping: a\n`(key, locale)` that has never been invalidated has no map entry and reads as\ngeneration 0, so a per-entry bump cannot reach it and a resolution that started\nbefore the clear would write its pre-clear value back.\n\n## Public API surface\n\n```typescript\nimport {\n defineLanguageString,\n resolveLanguageString,\n LanguageOverride,\n LanguageOverrideCollection,\n clearLanguageCache,\n} from '@happyvertical/smrt-languages';\n\ndefineLanguageString({\n key: 'users.role.member',\n locale: 'en',\n template: 'Member',\n});\n\nconst text = await resolveLanguageString('users.role.member', {\n db,\n tenantId: 'tenant-a',\n locale: 'es',\n vars: { name: 'Will' },\n});\n```\n",
|
|
666
|
+
"browser": {
|
|
667
|
+
"status": "server-only",
|
|
668
|
+
"issues": [
|
|
669
|
+
"#3615",
|
|
670
|
+
"#3618",
|
|
671
|
+
"#3624",
|
|
672
|
+
"#3627"
|
|
673
|
+
],
|
|
674
|
+
"reason": "node:crypto",
|
|
675
|
+
"via": [
|
|
676
|
+
"@happyvertical/smrt-features",
|
|
677
|
+
"@happyvertical/smrt-jobs",
|
|
678
|
+
"@happyvertical/smrt-tenancy"
|
|
679
|
+
]
|
|
680
|
+
}
|
|
666
681
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-languages",
|
|
3
|
-
"version": "0.55.
|
|
3
|
+
"version": "0.55.9",
|
|
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",
|
|
@@ -27,19 +27,19 @@
|
|
|
27
27
|
"./manifest.json": "./dist/manifest.json"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@happyvertical/ai": "^0.
|
|
31
|
-
"@happyvertical/logger": "^0.
|
|
32
|
-
"@happyvertical/smrt-config": "0.55.
|
|
33
|
-
"@happyvertical/smrt-core": "0.55.
|
|
34
|
-
"@happyvertical/smrt-features": "0.55.
|
|
35
|
-
"@happyvertical/smrt-jobs": "0.55.
|
|
36
|
-
"@happyvertical/smrt-prompts": "0.55.
|
|
37
|
-
"@happyvertical/smrt-tenancy": "0.55.
|
|
38
|
-
"@happyvertical/sql": "^0.
|
|
30
|
+
"@happyvertical/ai": "^0.103.1",
|
|
31
|
+
"@happyvertical/logger": "^0.103.1",
|
|
32
|
+
"@happyvertical/smrt-config": "0.55.9",
|
|
33
|
+
"@happyvertical/smrt-core": "0.55.9",
|
|
34
|
+
"@happyvertical/smrt-features": "0.55.9",
|
|
35
|
+
"@happyvertical/smrt-jobs": "0.55.9",
|
|
36
|
+
"@happyvertical/smrt-prompts": "0.55.9",
|
|
37
|
+
"@happyvertical/smrt-tenancy": "0.55.9",
|
|
38
|
+
"@happyvertical/sql": "^0.103.1"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@happyvertical/smrt-cli": "0.55.
|
|
42
|
-
"@happyvertical/smrt-vitest": "0.55.
|
|
41
|
+
"@happyvertical/smrt-cli": "0.55.9",
|
|
42
|
+
"@happyvertical/smrt-vitest": "0.55.9",
|
|
43
43
|
"@types/node": "24.13.6",
|
|
44
44
|
"typescript": "6.0.3",
|
|
45
45
|
"vite": "8.1.4",
|