@ankhorage/infra 0.3.5 → 0.3.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ankhorage/infra
2
2
 
3
+ ## 0.3.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 89eb7cf: Generate in-memory API store methods as explicit promises without unnecessary `async`, so generated apps pass `@typescript-eslint/require-await`.
8
+
3
9
  ## 0.3.5
4
10
 
5
11
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { generateApiInfrastructureArtifacts } from '../../apis';
1
+ import { generateApiInfrastructureArtifacts } from '../../apiArtifacts';
2
2
  import { generateAuthProviderArtifacts } from './auth';
3
3
  import { generateAuthorizationArtifacts } from './authz';
4
4
  import { generateMinikubeBaseArtifacts } from './base';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/minikube/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kCAAkC,EAAE,MAAM,YAAY,CAAC;AAOhE,OAAO,EAAE,6BAA6B,EAAE,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAE,8BAA8B,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EAAE,6BAA6B,EAAE,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,iBAAiB,GAAG,UAAU,CAAC;AAErC,MAAM,UAAU,qBAAqB,CACnC,QAA4B,EAC5B,UAA2C,EAAE;IAE7C,IAAI,QAAQ,CAAC,UAAU,EAAE,MAAM,KAAK,UAAU,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CACb,0EAA0E,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,WAAW,KAAK,CAC1H,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,QAAQ,EAAE,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC7E,MAAM,IAAI,KAAK,CACb,wDAAwD,QAAQ,CAAC,QAAQ,CAAC,QAAQ,oCAAoC,CACvH,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEtD,MAAM,aAAa,GAAG,6BAA6B,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7E,MAAM,cAAc,GAAG,8BAA8B,CAAC;QACpD,QAAQ;QACR,SAAS;QACT,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IACH,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,kCAAkC,CAAC;QACtD,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,IAAI;QAC/B,gBAAgB,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ;KAC9C,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,MAAM,CAAC;QAC5B,GAAG,aAAa,CAAC,SAAS;QAC1B,GAAG,cAAc,CAAC,SAAS;QAC3B,GAAG,gBAAgB,CAAC,SAAS;KAC9B,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,MAAM,CAAC;QAC7B,GAAG,aAAa,CAAC,UAAU;QAC3B,GAAG,cAAc,CAAC,UAAU;QAC5B,GAAG,gBAAgB,CAAC,UAAU;KAC/B,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,6BAA6B,CAAC;QAC9C,QAAQ;QACR,SAAS;QACT,cAAc;QACd,eAAe;KAChB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,MAAM,CAAC;QACtB,GAAG,eAAe,CAAC,QAAQ,CAAC;QAC5B,GAAG,aAAa,CAAC,QAAQ;QACzB,GAAG,cAAc,CAAC,QAAQ;QAC1B,GAAG,gBAAgB,CAAC,QAAQ;QAC5B,GAAG,YAAY,CAAC,QAAQ;KACzB,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,EAAE;YACL,GAAG,SAAS;YACZ,GAAG,aAAa,CAAC,KAAK;YACtB,GAAG,cAAc,CAAC,KAAK;YACvB,GAAG,gBAAgB,CAAC,KAAK;YACzB,GAAG,YAAY,CAAC,KAAK;SACtB;QACD,QAAQ;QACR,IAAI,EAAE;YACJ,MAAM,EAAE,UAAU;YAClB,SAAS,EAAE,gBAAgB,CAAC,QAAQ,CAAC;SACtC;QACD,YAAY,EAAE,mBAAmB,CAAC,QAAQ,CAAC;KAC5C,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,QAA4B;IACpD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,IAAI,QAAQ,CAAC,IAAI,EAAE,QAAQ;QAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnE,IAAI,QAAQ,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;QACzC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,QAAQ,CAAC,QAAQ,EAAE,QAAQ;QAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3E,IAAI,QAAQ,CAAC,OAAO,EAAE,QAAQ;QAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzE,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ;QAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAErE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED,SAAS,mBAAmB,CAAC,QAA4B;IACvD,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO;QACL;YACE,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,QAAQ;YACjB,MAAM,EAAE,0CAA0C;SACnD;KACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,QAA4B;IACnD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,QAAQ,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC;QACpC,QAAQ,CAAC,IAAI,CACX,0FAA0F,CAC3F,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC,+EAA+E,CAAC,CAAC;IACjG,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,gBAAgB,CACvB,QAA4B,EAC5B,OAAwC;IAExC,MAAM,MAAM,GACV,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,iBAAiB,CAAC;IAE5F,MAAM,UAAU,GAAG,MAAM;SACtB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAEzB,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACzD,OAAO,IAAI,IAAI,iBAAiB,CAAC;AACnC,CAAC;AAED,SAAS,MAAM,CAAC,MAAgB;IAC9B,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["import { generateApiInfrastructureArtifacts } from '../../apis';\nimport type {\n GeneratedPackageDependency,\n InfraManifestInput,\n InfrastructureGenerationOptions,\n InfrastructureGenerationResult,\n} from '../../types';\nimport { generateAuthProviderArtifacts } from './auth';\nimport { generateAuthorizationArtifacts } from './authz';\nimport { generateMinikubeBaseArtifacts } from './base';\nimport { generateStorageArtifacts } from './storage';\n\nconst DEFAULT_NAMESPACE = 'ankh-app';\n\nexport function generateMinikubeInfra(\n manifest: InfraManifestInput,\n options: InfrastructureGenerationOptions = {},\n): InfrastructureGenerationResult {\n if (manifest.deployment?.target !== 'minikube') {\n throw new Error(\n `Minikube adapter only supports deployment target \"minikube\" (received \"${manifest.deployment?.target ?? 'undefined'}\").`,\n );\n }\n\n if (manifest.database?.provider && manifest.database.provider !== 'supabase') {\n throw new Error(\n `Unsupported database provider for minikube adapter: \"${manifest.database.provider}\". Only \"supabase\" is implemented.`,\n );\n }\n\n const namespace = resolveNamespace(manifest, options);\n\n const authArtifacts = generateAuthProviderArtifacts({ manifest, namespace });\n const authzArtifacts = generateAuthorizationArtifacts({\n manifest,\n namespace,\n appManifest: options.appManifest,\n });\n const storageArtifacts = generateStorageArtifacts({ manifest, namespace });\n const apiArtifacts = generateApiInfrastructureArtifacts({\n data: options.appManifest?.data,\n databaseProvider: manifest.database?.provider,\n });\n\n const extraResources = unique([\n ...authArtifacts.resources,\n ...authzArtifacts.resources,\n ...storageArtifacts.resources,\n ]);\n const extraEnvEntries = unique([\n ...authArtifacts.envEntries,\n ...authzArtifacts.envEntries,\n ...storageArtifacts.envEntries,\n ]);\n\n const baseFiles = generateMinikubeBaseArtifacts({\n manifest,\n namespace,\n extraResources,\n extraEnvEntries,\n });\n\n const warnings = unique([\n ...collectWarnings(manifest),\n ...authArtifacts.warnings,\n ...authzArtifacts.warnings,\n ...storageArtifacts.warnings,\n ...apiArtifacts.warnings,\n ]);\n\n return {\n files: [\n ...baseFiles,\n ...authArtifacts.files,\n ...authzArtifacts.files,\n ...storageArtifacts.files,\n ...apiArtifacts.files,\n ],\n warnings,\n meta: {\n target: 'minikube',\n providers: collectProviders(manifest),\n },\n dependencies: collectDependencies(manifest),\n };\n}\n\nfunction collectProviders(manifest: InfraManifestInput): string[] {\n const providers = new Set<string>();\n\n if (manifest.auth?.provider) providers.add(manifest.auth.provider);\n if (manifest.auth?.authorization?.engine) {\n providers.add(manifest.auth.authorization.engine);\n }\n if (manifest.database?.provider) providers.add(manifest.database.provider);\n if (manifest.storage?.provider) providers.add(manifest.storage.provider);\n if (manifest.state?.provider) providers.add(manifest.state.provider);\n\n return [...providers].sort();\n}\n\nfunction collectDependencies(manifest: InfraManifestInput): readonly GeneratedPackageDependency[] {\n if (manifest.state?.provider !== 'legend') {\n return [];\n }\n\n return [\n {\n name: '@ankhorage/state-legend',\n version: '^0.1.0',\n reason: 'Selected by infra.state.provider=legend.',\n },\n ];\n}\n\nfunction collectWarnings(manifest: InfraManifestInput): string[] {\n const warnings: string[] = [];\n\n if (manifest.deployment?.monitoring) {\n warnings.push(\n 'Monitoring is enabled in manifest, but monitoring stack resources are not generated yet.',\n );\n }\n\n if (manifest.networking?.cdn) {\n warnings.push('CDN is enabled in manifest, but CDN resources are not generated for minikube.');\n }\n\n return warnings;\n}\n\nfunction resolveNamespace(\n manifest: InfraManifestInput,\n options: InfrastructureGenerationOptions,\n): string {\n const source =\n manifest.networking?.domain?.trim() ?? options.namespaceHint?.trim() ?? DEFAULT_NAMESPACE;\n\n const normalized = source\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n\n const safe = normalized.slice(0, 63).replace(/-+$/g, '');\n return safe || DEFAULT_NAMESPACE;\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/minikube/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { generateApiInfrastructureArtifacts } from '../../apiArtifacts';\nimport type {\n GeneratedPackageDependency,\n InfraManifestInput,\n InfrastructureGenerationOptions,\n InfrastructureGenerationResult,\n} from '../../types';\nimport { generateAuthProviderArtifacts } from './auth';\nimport { generateAuthorizationArtifacts } from './authz';\nimport { generateMinikubeBaseArtifacts } from './base';\nimport { generateStorageArtifacts } from './storage';\n\nconst DEFAULT_NAMESPACE = 'ankh-app';\n\nexport function generateMinikubeInfra(\n manifest: InfraManifestInput,\n options: InfrastructureGenerationOptions = {},\n): InfrastructureGenerationResult {\n if (manifest.deployment?.target !== 'minikube') {\n throw new Error(\n `Minikube adapter only supports deployment target \"minikube\" (received \"${manifest.deployment?.target ?? 'undefined'}\").`,\n );\n }\n\n if (manifest.database?.provider && manifest.database.provider !== 'supabase') {\n throw new Error(\n `Unsupported database provider for minikube adapter: \"${manifest.database.provider}\". Only \"supabase\" is implemented.`,\n );\n }\n\n const namespace = resolveNamespace(manifest, options);\n\n const authArtifacts = generateAuthProviderArtifacts({ manifest, namespace });\n const authzArtifacts = generateAuthorizationArtifacts({\n manifest,\n namespace,\n appManifest: options.appManifest,\n });\n const storageArtifacts = generateStorageArtifacts({ manifest, namespace });\n const apiArtifacts = generateApiInfrastructureArtifacts({\n data: options.appManifest?.data,\n databaseProvider: manifest.database?.provider,\n });\n\n const extraResources = unique([\n ...authArtifacts.resources,\n ...authzArtifacts.resources,\n ...storageArtifacts.resources,\n ]);\n const extraEnvEntries = unique([\n ...authArtifacts.envEntries,\n ...authzArtifacts.envEntries,\n ...storageArtifacts.envEntries,\n ]);\n\n const baseFiles = generateMinikubeBaseArtifacts({\n manifest,\n namespace,\n extraResources,\n extraEnvEntries,\n });\n\n const warnings = unique([\n ...collectWarnings(manifest),\n ...authArtifacts.warnings,\n ...authzArtifacts.warnings,\n ...storageArtifacts.warnings,\n ...apiArtifacts.warnings,\n ]);\n\n return {\n files: [\n ...baseFiles,\n ...authArtifacts.files,\n ...authzArtifacts.files,\n ...storageArtifacts.files,\n ...apiArtifacts.files,\n ],\n warnings,\n meta: {\n target: 'minikube',\n providers: collectProviders(manifest),\n },\n dependencies: collectDependencies(manifest),\n };\n}\n\nfunction collectProviders(manifest: InfraManifestInput): string[] {\n const providers = new Set<string>();\n\n if (manifest.auth?.provider) providers.add(manifest.auth.provider);\n if (manifest.auth?.authorization?.engine) {\n providers.add(manifest.auth.authorization.engine);\n }\n if (manifest.database?.provider) providers.add(manifest.database.provider);\n if (manifest.storage?.provider) providers.add(manifest.storage.provider);\n if (manifest.state?.provider) providers.add(manifest.state.provider);\n\n return [...providers].sort();\n}\n\nfunction collectDependencies(manifest: InfraManifestInput): readonly GeneratedPackageDependency[] {\n if (manifest.state?.provider !== 'legend') {\n return [];\n }\n\n return [\n {\n name: '@ankhorage/state-legend',\n version: '^0.1.0',\n reason: 'Selected by infra.state.provider=legend.',\n },\n ];\n}\n\nfunction collectWarnings(manifest: InfraManifestInput): string[] {\n const warnings: string[] = [];\n\n if (manifest.deployment?.monitoring) {\n warnings.push(\n 'Monitoring is enabled in manifest, but monitoring stack resources are not generated yet.',\n );\n }\n\n if (manifest.networking?.cdn) {\n warnings.push('CDN is enabled in manifest, but CDN resources are not generated for minikube.');\n }\n\n return warnings;\n}\n\nfunction resolveNamespace(\n manifest: InfraManifestInput,\n options: InfrastructureGenerationOptions,\n): string {\n const source =\n manifest.networking?.domain?.trim() ?? options.namespaceHint?.trim() ?? DEFAULT_NAMESPACE;\n\n const normalized = source\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n\n const safe = normalized.slice(0, 63).replace(/-+$/g, '');\n return safe || DEFAULT_NAMESPACE;\n}\n\nfunction unique(values: string[]): string[] {\n return [...new Set(values)];\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { AppDataManifest } from '@ankhorage/contracts';
2
+ import { type ApiInfrastructureArtifacts } from './apis';
3
+ export type { ApiInfrastructureArtifacts } from './apis';
4
+ export declare function generateApiInfrastructureArtifacts(args: {
5
+ readonly data: AppDataManifest | undefined;
6
+ readonly databaseProvider: string | undefined;
7
+ }): ApiInfrastructureArtifacts;
8
+ //# sourceMappingURL=apiArtifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiArtifacts.d.ts","sourceRoot":"","sources":["../src/apiArtifacts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,QAAQ,CAAC;AAIhB,YAAY,EAAE,0BAA0B,EAAE,MAAM,QAAQ,CAAC;AAEzD,wBAAgB,kCAAkC,CAAC,IAAI,EAAE;IACvD,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/C,GAAG,0BAA0B,CAW7B"}
@@ -0,0 +1,35 @@
1
+ import { generateApiInfrastructureArtifacts as generateRawApiInfrastructureArtifacts, } from './apis';
2
+ const GENERATED_API_HANDLERS_PATH = 'src/generated/apis/apiHandlers.ts';
3
+ export function generateApiInfrastructureArtifacts(args) {
4
+ const artifacts = generateRawApiInfrastructureArtifacts(args);
5
+ return {
6
+ ...artifacts,
7
+ files: artifacts.files.map((file) => file.path === GENERATED_API_HANDLERS_PATH
8
+ ? { ...file, content: makeGeneratedApiHandlersLintSafe(file.content) }
9
+ : file),
10
+ };
11
+ }
12
+ function makeGeneratedApiHandlersLintSafe(source) {
13
+ let result = source;
14
+ result = replaceGeneratedSnippet(result, ' async list(apiId: string): Promise<readonly GeneratedApiRecord[]> {', ' list(apiId: string): Promise<readonly GeneratedApiRecord[]> {');
15
+ result = replaceGeneratedSnippet(result, ' return getRows(records, apiId).map(cloneRecord);', ' return Promise.resolve(getRows(records, apiId).map(cloneRecord));');
16
+ result = replaceGeneratedSnippet(result, ' async read(apiId: string, id: string): Promise<GeneratedApiRecord | null> {', ' read(apiId: string, id: string): Promise<GeneratedApiRecord | null> {');
17
+ result = replaceGeneratedSnippet(result, ' if (primaryKey === null) return null;', ' if (primaryKey === null) return Promise.resolve(null);', 3);
18
+ result = replaceGeneratedSnippet(result, ' return record === undefined ? null : cloneRecord(record);', ' return Promise.resolve(record === undefined ? null : cloneRecord(record));');
19
+ result = replaceGeneratedSnippet(result, ' async create(apiId: string, values: GeneratedApiRecord): Promise<GeneratedApiRecord> {', ' create(apiId: string, values: GeneratedApiRecord): Promise<GeneratedApiRecord> {');
20
+ result = replaceGeneratedSnippet(result, ' return cloneRecord(nextRecord);', ' return Promise.resolve(cloneRecord(nextRecord));', 2);
21
+ result = replaceGeneratedSnippet(result, ' async update(\n', ' update(\n');
22
+ result = replaceGeneratedSnippet(result, ' if (index < 0) return null;', ' if (index < 0) return Promise.resolve(null);');
23
+ result = replaceGeneratedSnippet(result, ' async delete(apiId: string, id: string): Promise<GeneratedApiRecord | null> {', ' delete(apiId: string, id: string): Promise<GeneratedApiRecord | null> {');
24
+ result = replaceGeneratedSnippet(result, ' if (deleted === undefined) return null;', ' if (deleted === undefined) return Promise.resolve(null);');
25
+ result = replaceGeneratedSnippet(result, ' return cloneRecord(deleted);', ' return Promise.resolve(cloneRecord(deleted));');
26
+ return result;
27
+ }
28
+ function replaceGeneratedSnippet(source, snippet, replacement, expectedCount = 1) {
29
+ const count = source.split(snippet).length - 1;
30
+ if (count !== expectedCount) {
31
+ throw new Error(`Expected generated API handler snippet ${JSON.stringify(snippet)} ${expectedCount} time(s), found ${count}.`);
32
+ }
33
+ return source.replaceAll(snippet, replacement);
34
+ }
35
+ //# sourceMappingURL=apiArtifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiArtifacts.js","sourceRoot":"","sources":["../src/apiArtifacts.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,kCAAkC,IAAI,qCAAqC,GAE5E,MAAM,QAAQ,CAAC;AAEhB,MAAM,2BAA2B,GAAG,mCAAmC,CAAC;AAIxE,MAAM,UAAU,kCAAkC,CAAC,IAGlD;IACC,MAAM,SAAS,GAAG,qCAAqC,CAAC,IAAI,CAAC,CAAC;IAE9D,OAAO;QACL,GAAG,SAAS;QACZ,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAClC,IAAI,CAAC,IAAI,KAAK,2BAA2B;YACvC,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,gCAAgC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;YACtE,CAAC,CAAC,IAAI,CACT;KACF,CAAC;AACJ,CAAC;AAED,SAAS,gCAAgC,CAAC,MAAc;IACtD,IAAI,MAAM,GAAG,MAAM,CAAC;IAEpB,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,yEAAyE,EACzE,mEAAmE,CACpE,CAAC;IACF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,wDAAwD,EACxD,yEAAyE,CAC1E,CAAC;IACF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,iFAAiF,EACjF,2EAA2E,CAC5E,CAAC;IACF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,6CAA6C,EAC7C,8DAA8D,EAC9D,CAAC,CACF,CAAC;IACF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,iEAAiE,EACjE,kFAAkF,CACnF,CAAC;IACF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,4FAA4F,EAC5F,sFAAsF,CACvF,CAAC;IACF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,uCAAuC,EACvC,wDAAwD,EACxD,CAAC,CACF,CAAC;IACF,MAAM,GAAG,uBAAuB,CAAC,MAAM,EAAE,qBAAqB,EAAE,eAAe,CAAC,CAAC;IACjF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,mCAAmC,EACnC,oDAAoD,CACrD,CAAC;IACF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,mFAAmF,EACnF,6EAA6E,CAC9E,CAAC;IACF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,+CAA+C,EAC/C,gEAAgE,CACjE,CAAC;IACF,MAAM,GAAG,uBAAuB,CAC9B,MAAM,EACN,oCAAoC,EACpC,qDAAqD,CACtD,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,uBAAuB,CAC9B,MAAc,EACd,OAAe,EACf,WAAmB,EACnB,aAAa,GAAG,CAAC;IAEjB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/C,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,0CAA0C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,aAAa,mBAAmB,KAAK,GAAG,CAC9G,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AACjD,CAAC","sourcesContent":["import type { AppDataManifest } from '@ankhorage/contracts';\n\nimport {\n generateApiInfrastructureArtifacts as generateRawApiInfrastructureArtifacts,\n type ApiInfrastructureArtifacts,\n} from './apis';\n\nconst GENERATED_API_HANDLERS_PATH = 'src/generated/apis/apiHandlers.ts';\n\nexport type { ApiInfrastructureArtifacts } from './apis';\n\nexport function generateApiInfrastructureArtifacts(args: {\n readonly data: AppDataManifest | undefined;\n readonly databaseProvider: string | undefined;\n}): ApiInfrastructureArtifacts {\n const artifacts = generateRawApiInfrastructureArtifacts(args);\n\n return {\n ...artifacts,\n files: artifacts.files.map((file) =>\n file.path === GENERATED_API_HANDLERS_PATH\n ? { ...file, content: makeGeneratedApiHandlersLintSafe(file.content) }\n : file,\n ),\n };\n}\n\nfunction makeGeneratedApiHandlersLintSafe(source: string): string {\n let result = source;\n\n result = replaceGeneratedSnippet(\n result,\n ' async list(apiId: string): Promise<readonly GeneratedApiRecord[]> {',\n ' list(apiId: string): Promise<readonly GeneratedApiRecord[]> {',\n );\n result = replaceGeneratedSnippet(\n result,\n ' return getRows(records, apiId).map(cloneRecord);',\n ' return Promise.resolve(getRows(records, apiId).map(cloneRecord));',\n );\n result = replaceGeneratedSnippet(\n result,\n ' async read(apiId: string, id: string): Promise<GeneratedApiRecord | null> {',\n ' read(apiId: string, id: string): Promise<GeneratedApiRecord | null> {',\n );\n result = replaceGeneratedSnippet(\n result,\n ' if (primaryKey === null) return null;',\n ' if (primaryKey === null) return Promise.resolve(null);',\n 3,\n );\n result = replaceGeneratedSnippet(\n result,\n ' return record === undefined ? null : cloneRecord(record);',\n ' return Promise.resolve(record === undefined ? null : cloneRecord(record));',\n );\n result = replaceGeneratedSnippet(\n result,\n ' async create(apiId: string, values: GeneratedApiRecord): Promise<GeneratedApiRecord> {',\n ' create(apiId: string, values: GeneratedApiRecord): Promise<GeneratedApiRecord> {',\n );\n result = replaceGeneratedSnippet(\n result,\n ' return cloneRecord(nextRecord);',\n ' return Promise.resolve(cloneRecord(nextRecord));',\n 2,\n );\n result = replaceGeneratedSnippet(result, ' async update(\\n', ' update(\\n');\n result = replaceGeneratedSnippet(\n result,\n ' if (index < 0) return null;',\n ' if (index < 0) return Promise.resolve(null);',\n );\n result = replaceGeneratedSnippet(\n result,\n ' async delete(apiId: string, id: string): Promise<GeneratedApiRecord | null> {',\n ' delete(apiId: string, id: string): Promise<GeneratedApiRecord | null> {',\n );\n result = replaceGeneratedSnippet(\n result,\n ' if (deleted === undefined) return null;',\n ' if (deleted === undefined) return Promise.resolve(null);',\n );\n result = replaceGeneratedSnippet(\n result,\n ' return cloneRecord(deleted);',\n ' return Promise.resolve(cloneRecord(deleted));',\n );\n\n return result;\n}\n\nfunction replaceGeneratedSnippet(\n source: string,\n snippet: string,\n replacement: string,\n expectedCount = 1,\n): string {\n const count = source.split(snippet).length - 1;\n if (count !== expectedCount) {\n throw new Error(\n `Expected generated API handler snippet ${JSON.stringify(snippet)} ${expectedCount} time(s), found ${count}.`,\n );\n }\n\n return source.replaceAll(snippet, replacement);\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { InfraGenerationInput, InfraManifestInput, InfrastructureGenerationOptions, InfrastructureGenerationResult } from './types';
2
- export type { ApiInfrastructureArtifacts } from './apis';
3
- export { generateApiInfrastructureArtifacts } from './apis';
2
+ export type { ApiInfrastructureArtifacts } from './apiArtifacts';
3
+ export { generateApiInfrastructureArtifacts } from './apiArtifacts';
4
4
  export type { GeneratedFile, GeneratedInfrastructureFile, GeneratedPackageDependency, InfraDiagnostic, InfraGenerationInput, InfraGenerationOptions, InfraGenerationResult, InfraManifestInput, InfrastructureGenerationMeta, InfrastructureGenerationOptions, InfrastructureGenerationResult, PackageDependency, } from './types';
5
5
  export declare function generateInfra(input: InfraGenerationInput): InfrastructureGenerationResult;
6
6
  export declare function generateInfrastructure(manifest: InfraManifestInput, options?: InfrastructureGenerationOptions): InfrastructureGenerationResult;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,+BAA+B,EAC/B,8BAA8B,EAC/B,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,0BAA0B,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,kCAAkC,EAAE,MAAM,QAAQ,CAAC;AAC5D,YAAY,EACV,aAAa,EACb,2BAA2B,EAC3B,0BAA0B,EAC1B,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,EAC5B,+BAA+B,EAC/B,8BAA8B,EAC9B,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAEjB,wBAAgB,aAAa,CAAC,KAAK,EAAE,oBAAoB,GAAG,8BAA8B,CAEzF;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,+BAAoC,GAC5C,8BAA8B,CAUhC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,+BAA+B,EAC/B,8BAA8B,EAC/B,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,kCAAkC,EAAE,MAAM,gBAAgB,CAAC;AACpE,YAAY,EACV,aAAa,EACb,2BAA2B,EAC3B,0BAA0B,EAC1B,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,EAC5B,+BAA+B,EAC/B,8BAA8B,EAC9B,iBAAiB,GAClB,MAAM,SAAS,CAAC;AAEjB,wBAAgB,aAAa,CAAC,KAAK,EAAE,oBAAoB,GAAG,8BAA8B,CAEzF;AAED,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,+BAAoC,GAC5C,8BAA8B,CAUhC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { generateMinikubeInfra } from './adapters/minikube';
2
- export { generateApiInfrastructureArtifacts } from './apis';
2
+ export { generateApiInfrastructureArtifacts } from './apiArtifacts';
3
3
  export function generateInfra(input) {
4
4
  return generateInfrastructure(input.manifest, input.options ?? {});
5
5
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAS5D,OAAO,EAAE,kCAAkC,EAAE,MAAM,QAAQ,CAAC;AAgB5D,MAAM,UAAU,aAAa,CAAC,KAA2B;IACvD,OAAO,sBAAsB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,QAA4B,EAC5B,UAA2C,EAAE;IAE7C,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC","sourcesContent":["import { generateMinikubeInfra } from './adapters/minikube';\nimport type {\n InfraGenerationInput,\n InfraManifestInput,\n InfrastructureGenerationOptions,\n InfrastructureGenerationResult,\n} from './types';\n\nexport type { ApiInfrastructureArtifacts } from './apis';\nexport { generateApiInfrastructureArtifacts } from './apis';\nexport type {\n GeneratedFile,\n GeneratedInfrastructureFile,\n GeneratedPackageDependency,\n InfraDiagnostic,\n InfraGenerationInput,\n InfraGenerationOptions,\n InfraGenerationResult,\n InfraManifestInput,\n InfrastructureGenerationMeta,\n InfrastructureGenerationOptions,\n InfrastructureGenerationResult,\n PackageDependency,\n} from './types';\n\nexport function generateInfra(input: InfraGenerationInput): InfrastructureGenerationResult {\n return generateInfrastructure(input.manifest, input.options ?? {});\n}\n\nexport function generateInfrastructure(\n manifest: InfraManifestInput,\n options: InfrastructureGenerationOptions = {},\n): InfrastructureGenerationResult {\n if (!manifest.deployment) {\n throw new Error('Deployment configuration is missing.');\n }\n\n if (manifest.deployment.target !== 'minikube') {\n throw new Error(`Unsupported deployment target: ${manifest.deployment.target}`);\n }\n\n return generateMinikubeInfra(manifest, options);\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAS5D,OAAO,EAAE,kCAAkC,EAAE,MAAM,gBAAgB,CAAC;AAgBpE,MAAM,UAAU,aAAa,CAAC,KAA2B;IACvD,OAAO,sBAAsB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,QAA4B,EAC5B,UAA2C,EAAE;IAE7C,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,kCAAkC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC","sourcesContent":["import { generateMinikubeInfra } from './adapters/minikube';\nimport type {\n InfraGenerationInput,\n InfraManifestInput,\n InfrastructureGenerationOptions,\n InfrastructureGenerationResult,\n} from './types';\n\nexport type { ApiInfrastructureArtifacts } from './apiArtifacts';\nexport { generateApiInfrastructureArtifacts } from './apiArtifacts';\nexport type {\n GeneratedFile,\n GeneratedInfrastructureFile,\n GeneratedPackageDependency,\n InfraDiagnostic,\n InfraGenerationInput,\n InfraGenerationOptions,\n InfraGenerationResult,\n InfraManifestInput,\n InfrastructureGenerationMeta,\n InfrastructureGenerationOptions,\n InfrastructureGenerationResult,\n PackageDependency,\n} from './types';\n\nexport function generateInfra(input: InfraGenerationInput): InfrastructureGenerationResult {\n return generateInfrastructure(input.manifest, input.options ?? {});\n}\n\nexport function generateInfrastructure(\n manifest: InfraManifestInput,\n options: InfrastructureGenerationOptions = {},\n): InfrastructureGenerationResult {\n if (!manifest.deployment) {\n throw new Error('Deployment configuration is missing.');\n }\n\n if (manifest.deployment.target !== 'minikube') {\n throw new Error(`Unsupported deployment target: ${manifest.deployment.target}`);\n }\n\n return generateMinikubeInfra(manifest, options);\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ankhorage/infra",
3
3
  "type": "module",
4
- "version": "0.3.5",
4
+ "version": "0.3.6",
5
5
  "description": "Project-aware infrastructure generation library and executable Ankh provider for Ankhorage.",
6
6
  "homepage": "https://github.com/ankhorage/infra#readme",
7
7
  "bugs": {
@@ -1,4 +1,4 @@
1
- import { generateApiInfrastructureArtifacts } from '../../apis';
1
+ import { generateApiInfrastructureArtifacts } from '../../apiArtifacts';
2
2
  import type {
3
3
  GeneratedPackageDependency,
4
4
  InfraManifestInput,
@@ -0,0 +1,56 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+
3
+ import { generateApiInfrastructureArtifacts } from './apiArtifacts';
4
+
5
+ describe('generated API artifacts', () => {
6
+ test('emits lint-safe Promise-based memory-store methods', () => {
7
+ const result = generateApiInfrastructureArtifacts({
8
+ databaseProvider: 'supabase',
9
+ data: {
10
+ apis: {
11
+ items: {
12
+ id: 'items',
13
+ kind: 'generated',
14
+ label: 'Items',
15
+ description: 'Generated items API.',
16
+ basePath: '/api/items',
17
+ preset: 'crud',
18
+ resource: {
19
+ kind: 'collection',
20
+ collection: {
21
+ name: 'items',
22
+ primaryKey: 'id',
23
+ fields: [
24
+ { name: 'id', type: 'uuid', required: true, unique: true },
25
+ { name: 'name', type: 'text', required: true },
26
+ ],
27
+ },
28
+ seed: [],
29
+ },
30
+ endpoints: [
31
+ {
32
+ id: 'items.list',
33
+ method: 'GET',
34
+ path: '/',
35
+ intent: 'list',
36
+ },
37
+ ],
38
+ },
39
+ },
40
+ },
41
+ });
42
+
43
+ const handlers = result.files.find(
44
+ (file) => file.path === 'src/generated/apis/apiHandlers.ts',
45
+ );
46
+
47
+ expect(handlers).toBeDefined();
48
+ expect(handlers?.content).not.toMatch(/\basync (?:list|read|create|update|delete)\(/);
49
+ expect(handlers?.content).toContain(
50
+ 'list(apiId: string): Promise<readonly GeneratedApiRecord[]>',
51
+ );
52
+ expect(handlers?.content).toContain(
53
+ 'return Promise.resolve(getRows(records, apiId).map(cloneRecord));',
54
+ );
55
+ });
56
+ });
@@ -0,0 +1,107 @@
1
+ import type { AppDataManifest } from '@ankhorage/contracts';
2
+
3
+ import {
4
+ generateApiInfrastructureArtifacts as generateRawApiInfrastructureArtifacts,
5
+ type ApiInfrastructureArtifacts,
6
+ } from './apis';
7
+
8
+ const GENERATED_API_HANDLERS_PATH = 'src/generated/apis/apiHandlers.ts';
9
+
10
+ export type { ApiInfrastructureArtifacts } from './apis';
11
+
12
+ export function generateApiInfrastructureArtifacts(args: {
13
+ readonly data: AppDataManifest | undefined;
14
+ readonly databaseProvider: string | undefined;
15
+ }): ApiInfrastructureArtifacts {
16
+ const artifacts = generateRawApiInfrastructureArtifacts(args);
17
+
18
+ return {
19
+ ...artifacts,
20
+ files: artifacts.files.map((file) =>
21
+ file.path === GENERATED_API_HANDLERS_PATH
22
+ ? { ...file, content: makeGeneratedApiHandlersLintSafe(file.content) }
23
+ : file,
24
+ ),
25
+ };
26
+ }
27
+
28
+ function makeGeneratedApiHandlersLintSafe(source: string): string {
29
+ let result = source;
30
+
31
+ result = replaceGeneratedSnippet(
32
+ result,
33
+ ' async list(apiId: string): Promise<readonly GeneratedApiRecord[]> {',
34
+ ' list(apiId: string): Promise<readonly GeneratedApiRecord[]> {',
35
+ );
36
+ result = replaceGeneratedSnippet(
37
+ result,
38
+ ' return getRows(records, apiId).map(cloneRecord);',
39
+ ' return Promise.resolve(getRows(records, apiId).map(cloneRecord));',
40
+ );
41
+ result = replaceGeneratedSnippet(
42
+ result,
43
+ ' async read(apiId: string, id: string): Promise<GeneratedApiRecord | null> {',
44
+ ' read(apiId: string, id: string): Promise<GeneratedApiRecord | null> {',
45
+ );
46
+ result = replaceGeneratedSnippet(
47
+ result,
48
+ ' if (primaryKey === null) return null;',
49
+ ' if (primaryKey === null) return Promise.resolve(null);',
50
+ 3,
51
+ );
52
+ result = replaceGeneratedSnippet(
53
+ result,
54
+ ' return record === undefined ? null : cloneRecord(record);',
55
+ ' return Promise.resolve(record === undefined ? null : cloneRecord(record));',
56
+ );
57
+ result = replaceGeneratedSnippet(
58
+ result,
59
+ ' async create(apiId: string, values: GeneratedApiRecord): Promise<GeneratedApiRecord> {',
60
+ ' create(apiId: string, values: GeneratedApiRecord): Promise<GeneratedApiRecord> {',
61
+ );
62
+ result = replaceGeneratedSnippet(
63
+ result,
64
+ ' return cloneRecord(nextRecord);',
65
+ ' return Promise.resolve(cloneRecord(nextRecord));',
66
+ 2,
67
+ );
68
+ result = replaceGeneratedSnippet(result, ' async update(\n', ' update(\n');
69
+ result = replaceGeneratedSnippet(
70
+ result,
71
+ ' if (index < 0) return null;',
72
+ ' if (index < 0) return Promise.resolve(null);',
73
+ );
74
+ result = replaceGeneratedSnippet(
75
+ result,
76
+ ' async delete(apiId: string, id: string): Promise<GeneratedApiRecord | null> {',
77
+ ' delete(apiId: string, id: string): Promise<GeneratedApiRecord | null> {',
78
+ );
79
+ result = replaceGeneratedSnippet(
80
+ result,
81
+ ' if (deleted === undefined) return null;',
82
+ ' if (deleted === undefined) return Promise.resolve(null);',
83
+ );
84
+ result = replaceGeneratedSnippet(
85
+ result,
86
+ ' return cloneRecord(deleted);',
87
+ ' return Promise.resolve(cloneRecord(deleted));',
88
+ );
89
+
90
+ return result;
91
+ }
92
+
93
+ function replaceGeneratedSnippet(
94
+ source: string,
95
+ snippet: string,
96
+ replacement: string,
97
+ expectedCount = 1,
98
+ ): string {
99
+ const count = source.split(snippet).length - 1;
100
+ if (count !== expectedCount) {
101
+ throw new Error(
102
+ `Expected generated API handler snippet ${JSON.stringify(snippet)} ${expectedCount} time(s), found ${count}.`,
103
+ );
104
+ }
105
+
106
+ return source.replaceAll(snippet, replacement);
107
+ }
package/src/index.ts CHANGED
@@ -6,8 +6,8 @@ import type {
6
6
  InfrastructureGenerationResult,
7
7
  } from './types';
8
8
 
9
- export type { ApiInfrastructureArtifacts } from './apis';
10
- export { generateApiInfrastructureArtifacts } from './apis';
9
+ export type { ApiInfrastructureArtifacts } from './apiArtifacts';
10
+ export { generateApiInfrastructureArtifacts } from './apiArtifacts';
11
11
  export type {
12
12
  GeneratedFile,
13
13
  GeneratedInfrastructureFile,