@pikku/core 0.12.23 → 0.12.25

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.
Files changed (90) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/data-classification.d.ts +16 -0
  3. package/dist/data-classification.js +1 -0
  4. package/dist/function/function-runner.js +62 -15
  5. package/dist/function/functions.types.d.ts +8 -5
  6. package/dist/index.d.ts +5 -0
  7. package/dist/index.js +1 -0
  8. package/dist/middleware-runner.d.ts +2 -2
  9. package/dist/permissions.d.ts +1 -1
  10. package/dist/services/ai-agent-runner-service.d.ts +3 -0
  11. package/dist/services/audit-service.d.ts +50 -0
  12. package/dist/services/audit-service.js +106 -0
  13. package/dist/services/content-service.d.ts +1 -0
  14. package/dist/services/email-service.d.ts +36 -0
  15. package/dist/services/email-service.js +1 -0
  16. package/dist/services/gopass-secrets.d.ts +2 -35
  17. package/dist/services/gopass-secrets.js +10 -40
  18. package/dist/services/index.d.ts +5 -1
  19. package/dist/services/index.js +2 -0
  20. package/dist/services/local-content.js +1 -0
  21. package/dist/services/local-email-service.d.ts +4 -0
  22. package/dist/services/local-email-service.js +26 -0
  23. package/dist/services/local-secrets.d.ts +3 -36
  24. package/dist/services/local-secrets.js +12 -52
  25. package/dist/services/local-variables.d.ts +3 -5
  26. package/dist/services/local-variables.js +10 -10
  27. package/dist/services/meta-service.d.ts +36 -0
  28. package/dist/services/meta-service.js +59 -0
  29. package/dist/services/scoped-secret-service.d.ts +2 -3
  30. package/dist/services/scoped-secret-service.js +2 -6
  31. package/dist/services/secret-service.d.ts +5 -12
  32. package/dist/services/typed-secret-service.d.ts +3 -4
  33. package/dist/services/typed-secret-service.js +2 -5
  34. package/dist/services/typed-variables-service.d.ts +3 -6
  35. package/dist/services/typed-variables-service.js +0 -6
  36. package/dist/services/variables-service.d.ts +2 -4
  37. package/dist/testing/service-tests.js +13 -13
  38. package/dist/types/core.types.d.ts +15 -1
  39. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +2 -0
  40. package/dist/wirings/ai-agent/ai-agent-prepare.js +12 -3
  41. package/dist/wirings/ai-agent/ai-agent-runner.js +1 -1
  42. package/dist/wirings/ai-agent/ai-agent-stream.js +1 -1
  43. package/dist/wirings/ai-agent/ai-agent-utils.d.ts +1 -0
  44. package/dist/wirings/ai-agent/ai-agent-utils.js +1 -0
  45. package/dist/wirings/ai-agent/ai-agent.types.d.ts +4 -0
  46. package/dist/wirings/oauth2/oauth2-client.js +3 -3
  47. package/dist/wirings/rpc/rpc-runner.js +9 -2
  48. package/package.json +1 -1
  49. package/src/data-classification.ts +15 -0
  50. package/src/function/function-runner.test.ts +255 -0
  51. package/src/function/function-runner.ts +66 -20
  52. package/src/function/functions.types.ts +26 -11
  53. package/src/index.ts +44 -0
  54. package/src/middleware-runner.ts +10 -10
  55. package/src/permissions.ts +4 -4
  56. package/src/services/ai-agent-runner-service.ts +3 -0
  57. package/src/services/audit-service.test.ts +44 -0
  58. package/src/services/audit-service.ts +198 -0
  59. package/src/services/content-service.ts +1 -0
  60. package/src/services/email-service.ts +46 -0
  61. package/src/services/gopass-secrets.ts +10 -42
  62. package/src/services/index.ts +33 -0
  63. package/src/services/local-content.ts +1 -0
  64. package/src/services/local-email-service.test.ts +108 -0
  65. package/src/services/local-email-service.ts +30 -0
  66. package/src/services/local-secrets.test.ts +10 -10
  67. package/src/services/local-secrets.ts +16 -55
  68. package/src/services/local-variables.test.ts +4 -4
  69. package/src/services/local-variables.ts +12 -17
  70. package/src/services/meta-service.ts +115 -0
  71. package/src/services/scoped-secret-service.test.ts +10 -11
  72. package/src/services/scoped-secret-service.ts +4 -9
  73. package/src/services/secret-service.ts +5 -12
  74. package/src/services/typed-secret-service.test.ts +16 -17
  75. package/src/services/typed-secret-service.ts +5 -9
  76. package/src/services/typed-variables-service.test.ts +5 -5
  77. package/src/services/typed-variables-service.ts +5 -17
  78. package/src/services/variables-service.ts +2 -4
  79. package/src/testing/service-tests.ts +13 -13
  80. package/src/types/core.types.ts +20 -2
  81. package/src/wirings/ai-agent/ai-agent-prepare.ts +17 -3
  82. package/src/wirings/ai-agent/ai-agent-runner.test.ts +105 -0
  83. package/src/wirings/ai-agent/ai-agent-runner.ts +1 -1
  84. package/src/wirings/ai-agent/ai-agent-stream.ts +1 -1
  85. package/src/wirings/ai-agent/ai-agent-utils.ts +1 -0
  86. package/src/wirings/ai-agent/ai-agent.types.ts +4 -0
  87. package/src/wirings/oauth2/oauth2-client.test.ts +2 -3
  88. package/src/wirings/oauth2/oauth2-client.ts +3 -3
  89. package/src/wirings/rpc/rpc-runner.ts +9 -2
  90. package/tsconfig.tsbuildinfo +1 -1
@@ -8,6 +8,7 @@ export { TypedSecretService } from './typed-secret-service.js';
8
8
  export { PikkuCredentialWireService, createMiddlewareCredentialWireProps, createWireServicesCredentialWireProps, } from './credential-wire-service.js';
9
9
  export { TypedVariablesService } from './typed-variables-service.js';
10
10
  export { LocalSecretService } from './local-secrets.js';
11
+ export { LocalEmailService } from './local-email-service.js';
11
12
  export { LocalCredentialService } from './local-credential-service.js';
12
13
  export { LocalVariablesService } from './local-variables.js';
13
14
  export { ConsoleLogger, JsonConsoleLogger } from './logger-console.js';
@@ -18,6 +19,7 @@ export { InMemoryAIRunStateService } from './in-memory-ai-run-state-service.js';
18
19
  export { LocalGatewayService } from './local-gateway-service.js';
19
20
  export type { ContentService, SignContentKeyArgs, SignURLArgs, GetUploadURLArgs, UploadURLResult, BucketKeyArgs, WriteFileArgs, CopyFileArgs, } from './content-service.js';
20
21
  export type { JWTService } from './jwt-service.js';
22
+ export type { EmailService, EmailTemplateReference, SendEmailInput, SendEmailResult, SendHTMLEmailInput, SendTemplateEmailInput, SendTextEmailInput, } from './email-service.js';
21
23
  export type { Logger } from './logger.js';
22
24
  export type { SecretService } from './secret-service.js';
23
25
  export type { VariablesService } from './variables-service.js';
@@ -37,5 +39,7 @@ export type { CredentialStatusInfo, CredentialMetaInfo, } from './typed-credenti
37
39
  export type { VariableStatus, VariableMeta } from './typed-variables-service.js';
38
40
  export type { MetaService } from './meta-service.js';
39
41
  export type { SessionStore } from './session-store.js';
42
+ export { NoopAuditService, createInvocationAudit, resolveAuditActorFromWire, resolveAuditConfig, } from './audit-service.js';
43
+ export type { AuditActor, AuditConfig, AuditDurability, AuditEvent, AuditEventBatch, AuditLog, AuditLogWriteInput, AuditOutcome, AuditService, AuditSource, ResolvedAuditConfig, } from './audit-service.js';
40
44
  export { InMemorySessionStore } from './in-memory-session-store.js';
41
- export type { MCPMeta, RPCMetaRecord, ServiceMeta, ServicesMetaRecord, MiddlewareDefinitionMeta, MiddlewareInstanceMeta, GroupMeta, MiddlewareGroupsMeta, PermissionDefinitionMeta, PermissionsGroupsMeta, FunctionsMeta, FunctionMeta, MiddlewareMeta, PermissionMeta, AgentsMeta, AgentMeta, } from './meta-service.js';
45
+ export type { MCPMeta, RPCMetaRecord, ServiceMeta, ServicesMetaRecord, MiddlewareDefinitionMeta, MiddlewareInstanceMeta, GroupMeta, MiddlewareGroupsMeta, PermissionDefinitionMeta, PermissionsGroupsMeta, FunctionsMeta, FunctionMeta, MiddlewareMeta, PermissionMeta, AgentsMeta, AgentMeta, EmailsMeta, EmailTemplateMeta, EmailTemplateLocaleMeta, EmailTemplateAssets, } from './meta-service.js';
@@ -8,6 +8,7 @@ export { TypedSecretService } from './typed-secret-service.js';
8
8
  export { PikkuCredentialWireService, createMiddlewareCredentialWireProps, createWireServicesCredentialWireProps, } from './credential-wire-service.js';
9
9
  export { TypedVariablesService } from './typed-variables-service.js';
10
10
  export { LocalSecretService } from './local-secrets.js';
11
+ export { LocalEmailService } from './local-email-service.js';
11
12
  export { LocalCredentialService } from './local-credential-service.js';
12
13
  export { LocalVariablesService } from './local-variables.js';
13
14
  export { ConsoleLogger, JsonConsoleLogger } from './logger-console.js';
@@ -17,4 +18,5 @@ export { InMemoryTriggerService } from './in-memory-trigger-service.js';
17
18
  export { InMemoryAIRunStateService } from './in-memory-ai-run-state-service.js';
18
19
  export { LocalGatewayService } from './local-gateway-service.js';
19
20
  export { TypedCredentialService } from './typed-credential-service.js';
21
+ export { NoopAuditService, createInvocationAudit, resolveAuditActorFromWire, resolveAuditConfig, } from './audit-service.js';
20
22
  export { InMemorySessionStore } from './in-memory-session-store.js';
@@ -64,6 +64,7 @@ export class LocalContent {
64
64
  });
65
65
  }
66
66
  async getUploadURL(args) {
67
+ void args.visibility;
67
68
  const fullKey = this.joinKey(args.bucket, args.fileKey);
68
69
  this.logger.debug(`Going to upload with key: ${fullKey}`);
69
70
  return {
@@ -0,0 +1,4 @@
1
+ import type { EmailService, SendEmailInput, SendEmailResult } from './email-service.js';
2
+ export declare class LocalEmailService implements EmailService {
3
+ send(input: SendEmailInput): Promise<SendEmailResult>;
4
+ }
@@ -0,0 +1,26 @@
1
+ export class LocalEmailService {
2
+ async send(input) {
3
+ const payload = {
4
+ type: 'email',
5
+ message: 'this email was sent',
6
+ to: input.to,
7
+ from: input.from ?? null,
8
+ cc: input.cc ?? null,
9
+ bcc: input.bcc ?? null,
10
+ replyTo: input.replyTo ?? null,
11
+ subject: input.subject ?? null,
12
+ };
13
+ if ('template' in input && input.template) {
14
+ payload.template = input.template;
15
+ }
16
+ if ('html' in input && typeof input.html === 'string') {
17
+ payload.htmlLength = input.html.length;
18
+ payload.textLength = input.text?.length ?? null;
19
+ }
20
+ if ('text' in input && typeof input.text === 'string') {
21
+ payload.textLength = input.text.length;
22
+ }
23
+ console.info(JSON.stringify(payload));
24
+ return {};
25
+ }
26
+ }
@@ -7,43 +7,10 @@ import type { VariablesService } from './variables-service.js';
7
7
  export declare class LocalSecretService implements SecretService {
8
8
  private variables;
9
9
  private localSecrets;
10
- /**
11
- * Creates an instance of LocalSecretService.
12
- */
10
+ private parseSecret;
13
11
  constructor(variables?: VariablesService);
14
- /**
15
- * Retrieves a secret by key.
16
- * Checks local storage first, then falls back to environment variables.
17
- * @param key - The key of the secret to retrieve.
18
- * @returns A promise that resolves to the secret value.
19
- * @throws {Error} If the secret is not found.
20
- */
21
- getSecretJSON<R>(key: string): Promise<R>;
22
- /**
23
- * Retrieves a secret by key.
24
- * Checks local storage first, then falls back to environment variables.
25
- * @param key - The key of the secret to retrieve.
26
- * @returns A promise that resolves to the secret value.
27
- * @throws {Error} If the secret is not found.
28
- */
29
- getSecret(key: string): Promise<string>;
30
- /**
31
- * Stores a JSON value as a secret in local storage.
32
- * @param key - The key to store the secret under.
33
- * @param value - The JSON value to store.
34
- * @returns A promise that resolves when the secret is stored.
35
- */
36
- setSecretJSON(key: string, value: unknown): Promise<void>;
37
- /**
38
- * Checks if a secret exists without throwing.
39
- * @param key - The key of the secret to check.
40
- * @returns A promise that resolves to true if the secret exists.
41
- */
12
+ getSecret<T = string>(key: string): Promise<T>;
13
+ setSecret(key: string, value: unknown): Promise<void>;
42
14
  hasSecret(key: string): Promise<boolean>;
43
- /**
44
- * Deletes a secret from local storage.
45
- * @param key - The key of the secret to delete.
46
- * @returns A promise that resolves when the secret is deleted.
47
- */
48
15
  deleteSecret(key: string): Promise<void>;
49
16
  }
@@ -6,66 +6,31 @@ import { LocalVariablesService } from './local-variables.js';
6
6
  export class LocalSecretService {
7
7
  variables;
8
8
  localSecrets = new Map();
9
- /**
10
- * Creates an instance of LocalSecretService.
11
- */
12
- constructor(variables = new LocalVariablesService()) {
13
- this.variables = variables;
14
- }
15
- /**
16
- * Retrieves a secret by key.
17
- * Checks local storage first, then falls back to environment variables.
18
- * @param key - The key of the secret to retrieve.
19
- * @returns A promise that resolves to the secret value.
20
- * @throws {Error} If the secret is not found.
21
- */
22
- async getSecretJSON(key) {
23
- // Check local storage first
24
- const localValue = this.localSecrets.get(key);
25
- if (localValue) {
26
- return JSON.parse(localValue);
9
+ parseSecret(raw) {
10
+ try {
11
+ return JSON.parse(raw);
27
12
  }
28
- // Fall back to environment variables
29
- const value = await this.variables.get(key);
30
- if (value) {
31
- return JSON.parse(value);
13
+ catch {
14
+ return raw;
32
15
  }
33
- throw new Error('Requested secret not found');
34
16
  }
35
- /**
36
- * Retrieves a secret by key.
37
- * Checks local storage first, then falls back to environment variables.
38
- * @param key - The key of the secret to retrieve.
39
- * @returns A promise that resolves to the secret value.
40
- * @throws {Error} If the secret is not found.
41
- */
17
+ constructor(variables = new LocalVariablesService()) {
18
+ this.variables = variables;
19
+ }
42
20
  async getSecret(key) {
43
- // Check local storage first
44
21
  const localValue = this.localSecrets.get(key);
45
22
  if (localValue) {
46
- return localValue;
23
+ return this.parseSecret(localValue);
47
24
  }
48
- // Fall back to environment variables
49
25
  const value = await this.variables.get(key);
50
26
  if (value) {
51
- return value;
27
+ return this.parseSecret(value);
52
28
  }
53
29
  throw new Error('Requested secret not found');
54
30
  }
55
- /**
56
- * Stores a JSON value as a secret in local storage.
57
- * @param key - The key to store the secret under.
58
- * @param value - The JSON value to store.
59
- * @returns A promise that resolves when the secret is stored.
60
- */
61
- async setSecretJSON(key, value) {
62
- this.localSecrets.set(key, JSON.stringify(value));
31
+ async setSecret(key, value) {
32
+ this.localSecrets.set(key, typeof value === 'string' ? value : JSON.stringify(value));
63
33
  }
64
- /**
65
- * Checks if a secret exists without throwing.
66
- * @param key - The key of the secret to check.
67
- * @returns A promise that resolves to true if the secret exists.
68
- */
69
34
  async hasSecret(key) {
70
35
  if (this.localSecrets.has(key)) {
71
36
  return true;
@@ -73,11 +38,6 @@ export class LocalSecretService {
73
38
  const value = await this.variables.get(key);
74
39
  return value !== undefined && value !== null && value !== '';
75
40
  }
76
- /**
77
- * Deletes a secret from local storage.
78
- * @param key - The key of the secret to delete.
79
- * @returns A promise that resolves when the secret is deleted.
80
- */
81
41
  async deleteSecret(key) {
82
42
  this.localSecrets.delete(key);
83
43
  }
@@ -2,11 +2,9 @@ import type { VariablesService } from './variables-service.js';
2
2
  export declare class LocalVariablesService implements VariablesService {
3
3
  private variables;
4
4
  constructor(variables?: Record<string, string | undefined>);
5
- getAll(): Promise<Record<string, string | undefined>> | Record<string, string | undefined>;
6
- get(name: string): Promise<string | undefined> | string | undefined;
7
- getJSON<T = unknown>(name: string): T | undefined;
8
- set(name: string, value: string): void;
9
- setJSON(name: string, value: unknown): void;
5
+ getAll(): Record<string, string | undefined>;
6
+ get<T = string>(name: string): T | undefined;
7
+ set(name: string, value: unknown): void;
10
8
  has(name: string): boolean;
11
9
  delete(name: string): void;
12
10
  }
@@ -7,19 +7,19 @@ export class LocalVariablesService {
7
7
  return this.variables || {};
8
8
  }
9
9
  get(name) {
10
- return this.variables[name];
11
- }
12
- getJSON(name) {
13
- const value = this.variables[name];
14
- if (value === undefined)
10
+ const raw = this.variables[name];
11
+ if (raw === undefined)
15
12
  return undefined;
16
- return JSON.parse(value);
13
+ try {
14
+ return JSON.parse(raw);
15
+ }
16
+ catch {
17
+ return raw;
18
+ }
17
19
  }
18
20
  set(name, value) {
19
- this.variables[name] = value;
20
- }
21
- setJSON(name, value) {
22
- this.variables[name] = JSON.stringify(value);
21
+ this.variables[name] =
22
+ typeof value === 'string' ? value : JSON.stringify(value);
23
23
  }
24
24
  has(name) {
25
25
  return name in this.variables && this.variables[name] !== undefined;
@@ -86,6 +86,34 @@ export interface PermissionsGroupsMeta {
86
86
  httpGroups: Record<string, GroupMeta>;
87
87
  tagGroups: Record<string, GroupMeta>;
88
88
  }
89
+ export interface EmailTemplateLocaleMeta {
90
+ contentHash: string;
91
+ htmlHash: string;
92
+ subjectHash: string;
93
+ textHash: string;
94
+ }
95
+ export interface EmailTemplateMeta {
96
+ variables: string[];
97
+ hasHtml: boolean;
98
+ hasSubject: boolean;
99
+ hasText: boolean;
100
+ locales: Record<string, EmailTemplateLocaleMeta>;
101
+ }
102
+ export interface EmailsMeta {
103
+ src: string;
104
+ themeHash: string;
105
+ templates: Record<string, EmailTemplateMeta>;
106
+ }
107
+ export interface EmailTemplateAssets {
108
+ theme: Record<string, unknown>;
109
+ strings: Record<string, unknown>;
110
+ layout: string;
111
+ partials: Record<string, string>;
112
+ html: string;
113
+ subject: string;
114
+ text: string;
115
+ missing: string[];
116
+ }
89
117
  /**
90
118
  * Abstraction over .pikku metadata file access.
91
119
  * All paths are relative to the .pikku root directory.
@@ -100,6 +128,8 @@ export interface MetaService {
100
128
  readFile(relativePath: string): Promise<string | null>;
101
129
  /** List files in a directory by relative path. Returns empty array if not found. */
102
130
  readDir(relativePath: string): Promise<string[]>;
131
+ /** Read a project source file relative to the project root (one level above .pikku). */
132
+ readProjectFile(relativePath: string): Promise<string | null>;
103
133
  getHttpMeta(): Promise<HTTPWiringsMeta>;
104
134
  getChannelsMeta(): Promise<ChannelsMeta>;
105
135
  getSchedulerMeta(): Promise<ScheduledTasksMeta>;
@@ -117,6 +147,8 @@ export interface MetaService {
117
147
  getSecretsMeta(): Promise<SecretDefinitionsMeta>;
118
148
  getCredentialsMeta(): Promise<CredentialDefinitionsMeta>;
119
149
  getVariablesMeta(): Promise<VariableDefinitionsMeta>;
150
+ getEmailMeta(): Promise<EmailsMeta>;
151
+ getEmailTemplateAssets(templateName: string, locale: string): Promise<EmailTemplateAssets>;
120
152
  getServicesMeta(): Promise<ServicesMetaRecord>;
121
153
  getSchema(schemaName: string): Promise<JSONSchema7 | null>;
122
154
  getSchemas(schemaNames: string[]): Promise<Record<string, JSONSchema7 | null>>;
@@ -143,6 +175,7 @@ export declare class LocalMetaService implements MetaService {
143
175
  private secretsMetaCache;
144
176
  private credentialsMetaCache;
145
177
  private variablesMetaCache;
178
+ private emailMetaCache;
146
179
  private middlewareGroupsMetaCache;
147
180
  private permissionsGroupsMetaCache;
148
181
  private agentsMetaCache;
@@ -150,6 +183,7 @@ export declare class LocalMetaService implements MetaService {
150
183
  constructor(basePath: string);
151
184
  readFile(relativePath: string): Promise<string | null>;
152
185
  readDir(relativePath: string): Promise<string[]>;
186
+ readProjectFile(relativePath: string): Promise<string | null>;
153
187
  clearCache(): void;
154
188
  private readMetaJson;
155
189
  getHttpMeta(): Promise<HTTPWiringsMeta>;
@@ -169,6 +203,8 @@ export declare class LocalMetaService implements MetaService {
169
203
  getSecretsMeta(): Promise<SecretDefinitionsMeta>;
170
204
  getCredentialsMeta(): Promise<CredentialDefinitionsMeta>;
171
205
  getVariablesMeta(): Promise<VariableDefinitionsMeta>;
206
+ getEmailMeta(): Promise<EmailsMeta>;
207
+ getEmailTemplateAssets(templateName: string, locale: string): Promise<EmailTemplateAssets>;
172
208
  getServicesMeta(): Promise<ServicesMetaRecord>;
173
209
  getSchema(schemaName: string): Promise<JSONSchema7 | null>;
174
210
  getSchemas(schemaNames: string[]): Promise<Record<string, JSONSchema7 | null>>;
@@ -21,6 +21,7 @@ export class LocalMetaService {
21
21
  secretsMetaCache = null;
22
22
  credentialsMetaCache = null;
23
23
  variablesMetaCache = null;
24
+ emailMetaCache = null;
24
25
  middlewareGroupsMetaCache = null;
25
26
  permissionsGroupsMetaCache = null;
26
27
  agentsMetaCache = null;
@@ -44,6 +45,14 @@ export class LocalMetaService {
44
45
  return [];
45
46
  }
46
47
  }
48
+ async readProjectFile(relativePath) {
49
+ try {
50
+ return await readFile(join(this.basePath, '..', relativePath), 'utf-8');
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
47
56
  clearCache() {
48
57
  this.httpMetaCache = null;
49
58
  this.channelsMetaCache = null;
@@ -60,6 +69,7 @@ export class LocalMetaService {
60
69
  this.secretsMetaCache = null;
61
70
  this.credentialsMetaCache = null;
62
71
  this.variablesMetaCache = null;
72
+ this.emailMetaCache = null;
63
73
  this.middlewareGroupsMetaCache = null;
64
74
  this.permissionsGroupsMetaCache = null;
65
75
  this.agentsMetaCache = null;
@@ -257,6 +267,55 @@ export class LocalMetaService {
257
267
  this.variablesMetaCache = content ? JSON.parse(content) : {};
258
268
  return this.variablesMetaCache;
259
269
  }
270
+ async getEmailMeta() {
271
+ if (this.emailMetaCache)
272
+ return this.emailMetaCache;
273
+ const content = await this.readFile('email/pikku-emails-meta.gen.json');
274
+ this.emailMetaCache = content
275
+ ? JSON.parse(content)
276
+ : {
277
+ src: '',
278
+ themeHash: '',
279
+ templates: {},
280
+ };
281
+ return this.emailMetaCache;
282
+ }
283
+ async getEmailTemplateAssets(templateName, locale) {
284
+ const emailsMeta = await this.getEmailMeta();
285
+ if (!emailsMeta.src) {
286
+ throw new Error('No generated email metadata found. Run `pikku emails generate`.');
287
+ }
288
+ const baseDir = emailsMeta.src;
289
+ const [themeRaw, localeRaw, layoutRaw, footerRaw, templateHtml, templateSubject, templateText,] = await Promise.all([
290
+ this.readProjectFile(`${baseDir}/theme.json`),
291
+ this.readProjectFile(`${baseDir}/locales/${locale}.json`),
292
+ this.readProjectFile(`${baseDir}/partials/layout.html`),
293
+ this.readProjectFile(`${baseDir}/partials/footer.html`),
294
+ this.readProjectFile(`${baseDir}/templates/${templateName}.html`),
295
+ this.readProjectFile(`${baseDir}/templates/${templateName}.subject.txt`),
296
+ this.readProjectFile(`${baseDir}/templates/${templateName}.text.txt`),
297
+ ]);
298
+ return {
299
+ theme: themeRaw ? JSON.parse(themeRaw) : {},
300
+ strings: localeRaw
301
+ ? JSON.parse(localeRaw)
302
+ : {},
303
+ layout: layoutRaw ?? '',
304
+ partials: {
305
+ footer: footerRaw ?? '',
306
+ },
307
+ html: templateHtml ?? '',
308
+ subject: templateSubject ?? '',
309
+ text: templateText ?? '',
310
+ missing: [
311
+ ...(themeRaw ? [] : ['theme']),
312
+ ...(localeRaw ? [] : ['locale']),
313
+ ...(templateHtml ? [] : ['html']),
314
+ ...(templateSubject ? [] : ['subject']),
315
+ ...(templateText ? [] : ['text']),
316
+ ],
317
+ };
318
+ }
260
319
  async getServicesMeta() {
261
320
  if (this.servicesMetaCache)
262
321
  return this.servicesMetaCache;
@@ -8,9 +8,8 @@ export declare class ScopedSecretService implements SecretService {
8
8
  private allowedKeys;
9
9
  constructor(secrets: SecretService, allowedKeys: Set<string>);
10
10
  private assertAllowed;
11
- getSecret(key: string): Promise<string>;
12
- getSecretJSON<T = {}>(key: string): Promise<T>;
11
+ getSecret<T = string>(key: string): Promise<T>;
13
12
  hasSecret(key: string): Promise<boolean>;
14
- setSecretJSON(_key: string, _value: unknown): Promise<void>;
13
+ setSecret(_key: string, _value: unknown): Promise<void>;
15
14
  deleteSecret(_key: string): Promise<void>;
16
15
  }
@@ -18,16 +18,12 @@ export class ScopedSecretService {
18
18
  this.assertAllowed(key);
19
19
  return this.secrets.getSecret(key);
20
20
  }
21
- async getSecretJSON(key) {
22
- this.assertAllowed(key);
23
- return this.secrets.getSecretJSON(key);
24
- }
25
21
  async hasSecret(key) {
26
22
  this.assertAllowed(key);
27
23
  return this.secrets.hasSecret(key);
28
24
  }
29
- async setSecretJSON(_key, _value) {
30
- throw new Error('setSecretJSON is not allowed in scoped secret service');
25
+ async setSecret(_key, _value) {
26
+ throw new Error('setSecret is not allowed in scoped secret service');
31
27
  }
32
28
  async deleteSecret(_key) {
33
29
  throw new Error('deleteSecret is not allowed in scoped secret service');
@@ -3,19 +3,12 @@
3
3
  */
4
4
  export interface SecretService {
5
5
  /**
6
- * Retrieves a secret by key and parses it as JSON.
7
- * @param key - The key of the secret to retrieve.
8
- * @returns A promise that resolves to the parsed secret value.
9
- * @throws If the secret is not found.
10
- */
11
- getSecretJSON<Return = {}>(key: string): Promise<Return>;
12
- /**
13
- * Retrieves a secret by key as a string.
6
+ * Retrieves a secret by key, typed as T (defaults to string).
14
7
  * @param key - The key of the secret to retrieve.
15
8
  * @returns A promise that resolves to the secret value.
16
9
  * @throws If the secret is not found.
17
10
  */
18
- getSecret(key: string): Promise<string>;
11
+ getSecret<T = string>(key: string): Promise<T>;
19
12
  /**
20
13
  * Checks if a secret exists without throwing.
21
14
  * @param key - The key of the secret to check.
@@ -23,12 +16,12 @@ export interface SecretService {
23
16
  */
24
17
  hasSecret(key: string): Promise<boolean>;
25
18
  /**
26
- * Stores a JSON value as a secret.
19
+ * Stores a secret value.
27
20
  * @param key - The key to store the secret under.
28
- * @param value - The JSON value to store.
21
+ * @param value - The value to store.
29
22
  * @returns A promise that resolves when the secret is stored.
30
23
  */
31
- setSecretJSON(key: string, value: unknown): Promise<void>;
24
+ setSecret(key: string, value: unknown): Promise<void>;
32
25
  /**
33
26
  * Deletes a secret by key.
34
27
  * @param key - The key of the secret to delete.
@@ -19,11 +19,10 @@ export declare class TypedSecretService<TMap = Record<string, unknown>> implemen
19
19
  private secrets;
20
20
  private credentialsMeta;
21
21
  constructor(secrets: SecretService, credentialsMeta: Record<string, CredentialMeta>);
22
- getSecretJSON<K extends keyof TMap & string>(key: K): Promise<TMap[K]>;
23
- getSecretJSON<T = unknown>(key: string): Promise<T>;
24
- getSecret(key: string): Promise<string>;
22
+ getSecret<K extends keyof TMap & string>(key: K): Promise<TMap[K]>;
23
+ getSecret<T = string>(key: string): Promise<T>;
25
24
  hasSecret(key: string): Promise<boolean>;
26
- setSecretJSON<K extends string>(key: K, value: K extends keyof TMap ? TMap[K] : unknown): Promise<void>;
25
+ setSecret<K extends string>(key: K, value: K extends keyof TMap ? TMap[K] : unknown): Promise<void>;
27
26
  deleteSecret(key: string): Promise<void>;
28
27
  getAllStatus(): Promise<CredentialStatus[]>;
29
28
  getMissing(): Promise<CredentialStatus[]>;
@@ -5,17 +5,14 @@ export class TypedSecretService {
5
5
  this.secrets = secrets;
6
6
  this.credentialsMeta = credentialsMeta;
7
7
  }
8
- async getSecretJSON(key) {
9
- return this.secrets.getSecretJSON(key);
10
- }
11
8
  async getSecret(key) {
12
9
  return this.secrets.getSecret(key);
13
10
  }
14
11
  async hasSecret(key) {
15
12
  return this.secrets.hasSecret(key);
16
13
  }
17
- async setSecretJSON(key, value) {
18
- return this.secrets.setSecretJSON(key, value);
14
+ async setSecret(key, value) {
15
+ return this.secrets.setSecret(key, value);
19
16
  }
20
17
  async deleteSecret(key) {
21
18
  return this.secrets.deleteSecret(key);
@@ -13,13 +13,10 @@ export declare class TypedVariablesService<TMap = Record<string, unknown>> imple
13
13
  private variables;
14
14
  private variablesMeta;
15
15
  constructor(variables: VariablesService, variablesMeta: Record<string, VariableMeta>);
16
- get(name: keyof TMap & string): Promise<string | undefined> | string | undefined;
17
- get(name: string): Promise<string | undefined> | string | undefined;
18
- getJSON<K extends keyof TMap & string>(name: K): Promise<TMap[K] | undefined> | TMap[K] | undefined;
19
- getJSON<T = unknown>(name: string): Promise<T | undefined> | T | undefined;
16
+ get<K extends keyof TMap & string>(name: K): Promise<TMap[K] | undefined> | TMap[K] | undefined;
17
+ get<T = string>(name: string): Promise<T | undefined> | T | undefined;
20
18
  getAll(): Promise<Record<string, string | undefined>> | Record<string, string | undefined>;
21
- set(name: string, value: string): Promise<void> | void;
22
- setJSON(name: string, value: unknown): Promise<void> | void;
19
+ set(name: string, value: unknown): Promise<void> | void;
23
20
  has(name: string): Promise<boolean> | boolean;
24
21
  delete(name: string): Promise<void> | void;
25
22
  getAllStatus(): Promise<VariableStatus[]>;
@@ -8,18 +8,12 @@ export class TypedVariablesService {
8
8
  get(name) {
9
9
  return this.variables.get(name);
10
10
  }
11
- getJSON(name) {
12
- return this.variables.getJSON(name);
13
- }
14
11
  getAll() {
15
12
  return this.variables.getAll();
16
13
  }
17
14
  set(name, value) {
18
15
  return this.variables.set(name, value);
19
16
  }
20
- setJSON(name, value) {
21
- return this.variables.setJSON(name, value);
22
- }
23
17
  has(name) {
24
18
  return this.variables.has(name);
25
19
  }
@@ -1,9 +1,7 @@
1
1
  export interface VariablesService {
2
- get: (name: string) => Promise<string | undefined> | string | undefined;
3
- getJSON: <T = unknown>(name: string) => Promise<T | undefined> | T | undefined;
2
+ get<T = string>(name: string): Promise<T | undefined> | T | undefined;
4
3
  getAll: () => Promise<Record<string, string | undefined>> | Record<string, string | undefined>;
5
- set: (name: string, value: string) => Promise<void> | void;
6
- setJSON: (name: string, value: unknown) => Promise<void> | void;
4
+ set: (name: string, value: unknown) => Promise<void> | void;
7
5
  has: (name: string) => Promise<boolean> | boolean;
8
6
  delete: (name: string) => Promise<void> | void;
9
7
  }