@ankhorage/infra 2.0.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/dist/project.js +2 -2
- package/dist/project.js.map +1 -1
- package/dist/testSupport.js +1 -1
- package/dist/testSupport.js.map +1 -1
- package/package.json +2 -2
- package/src/adapters/minikube/auth/supabase/index.test.ts +1 -1
- package/src/adapters/minikube/auth/supabase/oauthRuntime.test.ts +1 -1
- package/src/adapters/minikube/auth/supabase/profile.integration.test.ts +1 -1
- package/src/adapters/minikube/auth/supabase/providerAssignments.test.ts +1 -1
- package/src/adapters/minikube/base/appImageBuild.test.ts +1 -1
- package/src/adapters/minikube/base/index.test.ts +2 -2
- package/src/adapters/minikube/base/twoAppIsolation.integration.test.ts +2 -2
- package/src/adapters/minikube/secrets/index.test.ts +1 -1
- package/src/commands.test.ts +3 -3
- package/src/generatedApiDatabase.test.ts +1 -1
- package/src/index.test.ts +6 -6
- package/src/minikubeImageLifecycle.test.ts +1 -1
- package/src/project.test.ts +2 -2
- package/src/project.ts +2 -2
- package/src/projectInfrastructure.test.ts +5 -5
- package/src/testSupport.ts +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# INFRA
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Executable infra provider and standalone CLI for Ankhorage project workflows.
|
|
9
9
|
|
package/dist/project.js
CHANGED
|
@@ -52,7 +52,7 @@ function createFallbackManifest(projectId) {
|
|
|
52
52
|
themes: [],
|
|
53
53
|
activeThemeId: 'default',
|
|
54
54
|
infra: {
|
|
55
|
-
|
|
55
|
+
modules: [],
|
|
56
56
|
},
|
|
57
57
|
navigator: {
|
|
58
58
|
type: 'stack',
|
|
@@ -142,7 +142,7 @@ function isAppManifestMetadata(value) {
|
|
|
142
142
|
(value.updated === undefined || typeof value.updated === 'string'));
|
|
143
143
|
}
|
|
144
144
|
function isInfraManifestRecord(value) {
|
|
145
|
-
return isRecord(value) && Array.isArray(value.
|
|
145
|
+
return isRecord(value) && Array.isArray(value.modules);
|
|
146
146
|
}
|
|
147
147
|
function isNavigatorSpec(value) {
|
|
148
148
|
return (isRecord(value) &&
|
package/dist/project.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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","sourcesContent":["import { APP_CATEGORIES, type AppManifest, type NavigatorSpec } from '@ankhorage/contracts';\nimport { promises as fs } from 'fs';\nimport path from 'path';\n\nexport interface ResolvedInfraProject {\n readonly appsRoot: string;\n readonly manifest: AppManifest;\n readonly manifestPath: string;\n readonly projectId: string;\n readonly projectPath: string;\n readonly workspaceRoot: string;\n}\n\nexport async function resolveInfraProject(options: {\n readonly cwd: string;\n readonly projectId?: string;\n}): Promise<ResolvedInfraProject> {\n const workspaceRoot = await findWorkspaceRoot(options.cwd);\n if (workspaceRoot === null) {\n throw new Error(`Could not find an Ankh workspace root from cwd: ${options.cwd}`);\n }\n\n const appsRoot = path.join(workspaceRoot, 'apps');\n const projectId =\n options.projectId === undefined\n ? inferProjectId(options.cwd, appsRoot)\n : validateExplicitProjectId(options.projectId);\n if (projectId === null) {\n throw new Error(\n 'Could not infer a project from cwd. Pass a project id or run the command inside apps/<project>.',\n );\n }\n\n const projectPath = resolveProjectPath(appsRoot, projectId);\n if (!(await pathExists(projectPath))) {\n throw new Error(`Project '${projectId}' not found.`);\n }\n\n const manifestPath = path.join(projectPath, 'ankh.config.json');\n const manifest = await readProjectManifest({\n manifestPath,\n projectId,\n projectPath,\n });\n\n return {\n appsRoot,\n manifest,\n manifestPath,\n projectId,\n projectPath,\n workspaceRoot,\n };\n}\n\nfunction resolveProjectPath(appsRoot: string, projectId: string): string {\n const projectPath = path.resolve(appsRoot, projectId);\n const appsRootPath = `${path.resolve(appsRoot)}${path.sep}`;\n\n if (!projectPath.startsWith(appsRootPath)) {\n throw new Error('Security check failed while resolving the project path.');\n }\n\n return projectPath;\n}\n\nfunction createFallbackManifest(projectId: string): AppManifest {\n return {\n metadata: {\n name: projectId,\n slug: projectId,\n version: '0.0.0',\n category: 'developer_tools',\n themeId: 'default',\n },\n themes: [],\n activeThemeId: 'default',\n infra: {\n plugins: [],\n },\n navigator: {\n type: 'stack',\n routes: [{ name: 'index', screenId: 'index' }],\n },\n screens: {},\n settings: {\n localization: {\n defaultLocale: 'en',\n locales: ['en'],\n },\n },\n };\n}\n\nasync function readProjectManifest(args: {\n readonly manifestPath: string;\n readonly projectId: string;\n readonly projectPath: string;\n}): Promise<AppManifest> {\n if (!(await pathExists(args.manifestPath))) {\n return createFallbackManifest(args.projectId);\n }\n\n const rawManifest = await fs.readFile(args.manifestPath, 'utf8');\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawManifest);\n } catch (error) {\n throw new Error(\n `Project manifest is not valid JSON: ${args.manifestPath}: ${getErrorMessage(error)}`,\n { cause: error },\n );\n }\n\n if (!isAppManifest(parsed)) {\n throw new Error(`Project manifest has an invalid shape: ${args.manifestPath}`);\n }\n\n return parsed;\n}\n\nasync function findWorkspaceRoot(startPath: string): Promise<string | null> {\n let currentPath = path.resolve(startPath);\n\n for (;;) {\n const appsRoot = path.join(currentPath, 'apps');\n if (await isDirectory(appsRoot)) {\n return currentPath;\n }\n\n const parentPath = path.dirname(currentPath);\n if (parentPath === currentPath) {\n return null;\n }\n\n currentPath = parentPath;\n }\n}\n\nfunction inferProjectId(cwd: string, appsRoot: string): string | null {\n const relativePath = path.relative(path.resolve(appsRoot), path.resolve(cwd));\n if (relativePath === '' || relativePath.startsWith('..') || path.isAbsolute(relativePath)) {\n return null;\n }\n\n const [projectId] = relativePath.split(path.sep);\n return projectId === undefined || projectId.length === 0 ? null : path.basename(projectId);\n}\n\nfunction validateExplicitProjectId(projectId: string): string {\n if (projectId.trim().length === 0) {\n throw new Error('Invalid project id: expected a single safe project segment.');\n }\n\n if (\n projectId === '.' ||\n projectId === '..' ||\n path.isAbsolute(projectId) ||\n projectId.includes('/') ||\n projectId.includes('\\\\')\n ) {\n throw new Error(`Invalid project id: ${projectId}. Expected a single safe project segment.`);\n }\n\n return projectId;\n}\n\nfunction isAppManifest(value: unknown): value is AppManifest {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n isAppManifestMetadata(value.metadata) &&\n Array.isArray(value.themes) &&\n typeof value.activeThemeId === 'string' &&\n isInfraManifestRecord(value.infra) &&\n isNavigatorSpec(value.navigator) &&\n isRecord(value.screens) &&\n isSettingsRecord(value.settings)\n );\n}\n\nfunction isAppManifestMetadata(value: unknown): value is AppManifest['metadata'] {\n return (\n isRecord(value) &&\n typeof value.name === 'string' &&\n typeof value.slug === 'string' &&\n typeof value.version === 'string' &&\n APP_CATEGORIES.some((category) => category === value.category) &&\n typeof value.themeId === 'string' &&\n (value.created === undefined || typeof value.created === 'string') &&\n (value.updated === undefined || typeof value.updated === 'string')\n );\n}\n\nfunction isInfraManifestRecord(value: unknown): value is AppManifest['infra'] {\n return isRecord(value) && Array.isArray(value.plugins);\n}\n\nfunction isNavigatorSpec(value: unknown): value is NavigatorSpec {\n return (\n isRecord(value) &&\n typeof value.type === 'string' &&\n Array.isArray(value.routes) &&\n (value.initialRouteName === undefined || typeof value.initialRouteName === 'string')\n );\n}\n\nfunction isSettingsRecord(value: unknown): value is AppManifest['settings'] {\n return (\n isRecord(value) &&\n (value.apiBaseUrl === undefined || typeof value.apiBaseUrl === 'string') &&\n isLocalizationRecord(value.localization)\n );\n}\n\nfunction isLocalizationRecord(value: unknown): value is AppManifest['settings']['localization'] {\n return (\n isRecord(value) &&\n typeof value.defaultLocale === 'string' &&\n Array.isArray(value.locales) &&\n value.locales.every((locale) => typeof locale === 'string')\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nasync function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAwC,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,IAAI,MAAM,MAAM,CAAC;AAWxB,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAGzC;IACC,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3D,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,mDAAmD,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,SAAS,GACb,OAAO,CAAC,SAAS,KAAK,SAAS;QAC7B,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC;QACvC,CAAC,CAAC,yBAAyB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,iGAAiG,CAClG,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC5D,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,YAAY,SAAS,cAAc,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC;QACzC,YAAY;QACZ,SAAS;QACT,WAAW;KACZ,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ;QACR,QAAQ;QACR,YAAY;QACZ,SAAS;QACT,WAAW;QACX,aAAa;KACd,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB,EAAE,SAAiB;IAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE5D,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,sBAAsB,CAAC,SAAiB;IAC/C,OAAO;QACL,QAAQ,EAAE;YACR,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE,iBAAiB;YAC3B,OAAO,EAAE,SAAS;SACnB;QACD,MAAM,EAAE,EAAE;QACV,aAAa,EAAE,SAAS;QACxB,KAAK,EAAE;YACL,OAAO,EAAE,EAAE;SACZ;QACD,SAAS,EAAE;YACT,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;SAC/C;QACD,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE;YACR,YAAY,EAAE;gBACZ,aAAa,EAAE,IAAI;gBACnB,OAAO,EAAE,CAAC,IAAI,CAAC;aAChB;SACF;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,IAIlC;IACC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QAC3C,OAAO,sBAAsB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAEjE,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,uCAAuC,IAAI,CAAC,YAAY,KAAK,eAAe,CAAC,KAAK,CAAC,EAAE,EACrF,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;IACjF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IAChD,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAE1C,SAAS,CAAC;QACR,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAChD,IAAI,MAAM,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC7C,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,WAAW,GAAG,UAAU,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,GAAW,EAAE,QAAgB;IACnD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,IAAI,YAAY,KAAK,EAAE,IAAI,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1F,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjD,OAAO,SAAS,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC7F,CAAC;AAED,SAAS,yBAAyB,CAAC,SAAiB;IAClD,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IAED,IACE,SAAS,KAAK,GAAG;QACjB,SAAS,KAAK,IAAI;QAClB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAC1B,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC;QACvB,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EACxB,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uBAAuB,SAAS,2CAA2C,CAAC,CAAC;IAC/F,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CACL,qBAAqB,CAAC,KAAK,CAAC,QAAQ,CAAC;QACrC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QAC3B,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ;QACvC,qBAAqB,CAAC,KAAK,CAAC,KAAK,CAAC;QAClC,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC;QAChC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;QACvB,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,CACjC,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc;IAC3C,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAC;QAC9D,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC;QAClE,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CACnE,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc;IAC3C,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QAC9B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QAC3B,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ,CAAC,CACrF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC;QACxE,oBAAoB,CAAC,KAAK,CAAC,YAAY,CAAC,CACzC,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ;QACvC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;QAC5B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAC5D,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,QAAgB;IACzC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import { APP_CATEGORIES, type AppManifest, type NavigatorSpec } from '@ankhorage/contracts';\nimport { promises as fs } from 'fs';\nimport path from 'path';\n\nexport interface ResolvedInfraProject {\n readonly appsRoot: string;\n readonly manifest: AppManifest;\n readonly manifestPath: string;\n readonly projectId: string;\n readonly projectPath: string;\n readonly workspaceRoot: string;\n}\n\nexport async function resolveInfraProject(options: {\n readonly cwd: string;\n readonly projectId?: string;\n}): Promise<ResolvedInfraProject> {\n const workspaceRoot = await findWorkspaceRoot(options.cwd);\n if (workspaceRoot === null) {\n throw new Error(`Could not find an Ankh workspace root from cwd: ${options.cwd}`);\n }\n\n const appsRoot = path.join(workspaceRoot, 'apps');\n const projectId =\n options.projectId === undefined\n ? inferProjectId(options.cwd, appsRoot)\n : validateExplicitProjectId(options.projectId);\n if (projectId === null) {\n throw new Error(\n 'Could not infer a project from cwd. Pass a project id or run the command inside apps/<project>.',\n );\n }\n\n const projectPath = resolveProjectPath(appsRoot, projectId);\n if (!(await pathExists(projectPath))) {\n throw new Error(`Project '${projectId}' not found.`);\n }\n\n const manifestPath = path.join(projectPath, 'ankh.config.json');\n const manifest = await readProjectManifest({\n manifestPath,\n projectId,\n projectPath,\n });\n\n return {\n appsRoot,\n manifest,\n manifestPath,\n projectId,\n projectPath,\n workspaceRoot,\n };\n}\n\nfunction resolveProjectPath(appsRoot: string, projectId: string): string {\n const projectPath = path.resolve(appsRoot, projectId);\n const appsRootPath = `${path.resolve(appsRoot)}${path.sep}`;\n\n if (!projectPath.startsWith(appsRootPath)) {\n throw new Error('Security check failed while resolving the project path.');\n }\n\n return projectPath;\n}\n\nfunction createFallbackManifest(projectId: string): AppManifest {\n return {\n metadata: {\n name: projectId,\n slug: projectId,\n version: '0.0.0',\n category: 'developer_tools',\n themeId: 'default',\n },\n themes: [],\n activeThemeId: 'default',\n infra: {\n modules: [],\n },\n navigator: {\n type: 'stack',\n routes: [{ name: 'index', screenId: 'index' }],\n },\n screens: {},\n settings: {\n localization: {\n defaultLocale: 'en',\n locales: ['en'],\n },\n },\n };\n}\n\nasync function readProjectManifest(args: {\n readonly manifestPath: string;\n readonly projectId: string;\n readonly projectPath: string;\n}): Promise<AppManifest> {\n if (!(await pathExists(args.manifestPath))) {\n return createFallbackManifest(args.projectId);\n }\n\n const rawManifest = await fs.readFile(args.manifestPath, 'utf8');\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(rawManifest);\n } catch (error) {\n throw new Error(\n `Project manifest is not valid JSON: ${args.manifestPath}: ${getErrorMessage(error)}`,\n { cause: error },\n );\n }\n\n if (!isAppManifest(parsed)) {\n throw new Error(`Project manifest has an invalid shape: ${args.manifestPath}`);\n }\n\n return parsed;\n}\n\nasync function findWorkspaceRoot(startPath: string): Promise<string | null> {\n let currentPath = path.resolve(startPath);\n\n for (;;) {\n const appsRoot = path.join(currentPath, 'apps');\n if (await isDirectory(appsRoot)) {\n return currentPath;\n }\n\n const parentPath = path.dirname(currentPath);\n if (parentPath === currentPath) {\n return null;\n }\n\n currentPath = parentPath;\n }\n}\n\nfunction inferProjectId(cwd: string, appsRoot: string): string | null {\n const relativePath = path.relative(path.resolve(appsRoot), path.resolve(cwd));\n if (relativePath === '' || relativePath.startsWith('..') || path.isAbsolute(relativePath)) {\n return null;\n }\n\n const [projectId] = relativePath.split(path.sep);\n return projectId === undefined || projectId.length === 0 ? null : path.basename(projectId);\n}\n\nfunction validateExplicitProjectId(projectId: string): string {\n if (projectId.trim().length === 0) {\n throw new Error('Invalid project id: expected a single safe project segment.');\n }\n\n if (\n projectId === '.' ||\n projectId === '..' ||\n path.isAbsolute(projectId) ||\n projectId.includes('/') ||\n projectId.includes('\\\\')\n ) {\n throw new Error(`Invalid project id: ${projectId}. Expected a single safe project segment.`);\n }\n\n return projectId;\n}\n\nfunction isAppManifest(value: unknown): value is AppManifest {\n if (!isRecord(value)) {\n return false;\n }\n\n return (\n isAppManifestMetadata(value.metadata) &&\n Array.isArray(value.themes) &&\n typeof value.activeThemeId === 'string' &&\n isInfraManifestRecord(value.infra) &&\n isNavigatorSpec(value.navigator) &&\n isRecord(value.screens) &&\n isSettingsRecord(value.settings)\n );\n}\n\nfunction isAppManifestMetadata(value: unknown): value is AppManifest['metadata'] {\n return (\n isRecord(value) &&\n typeof value.name === 'string' &&\n typeof value.slug === 'string' &&\n typeof value.version === 'string' &&\n APP_CATEGORIES.some((category) => category === value.category) &&\n typeof value.themeId === 'string' &&\n (value.created === undefined || typeof value.created === 'string') &&\n (value.updated === undefined || typeof value.updated === 'string')\n );\n}\n\nfunction isInfraManifestRecord(value: unknown): value is AppManifest['infra'] {\n return isRecord(value) && Array.isArray(value.modules);\n}\n\nfunction isNavigatorSpec(value: unknown): value is NavigatorSpec {\n return (\n isRecord(value) &&\n typeof value.type === 'string' &&\n Array.isArray(value.routes) &&\n (value.initialRouteName === undefined || typeof value.initialRouteName === 'string')\n );\n}\n\nfunction isSettingsRecord(value: unknown): value is AppManifest['settings'] {\n return (\n isRecord(value) &&\n (value.apiBaseUrl === undefined || typeof value.apiBaseUrl === 'string') &&\n isLocalizationRecord(value.localization)\n );\n}\n\nfunction isLocalizationRecord(value: unknown): value is AppManifest['settings']['localization'] {\n return (\n isRecord(value) &&\n typeof value.defaultLocale === 'string' &&\n Array.isArray(value.locales) &&\n value.locales.every((locale) => typeof locale === 'string')\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nasync function isDirectory(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
|
package/dist/testSupport.js
CHANGED
|
@@ -40,7 +40,7 @@ export async function createWorkspaceFixture(args = {}) {
|
|
|
40
40
|
rootPath,
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
export function createAppManifest(projectId, infra = {
|
|
43
|
+
export function createAppManifest(projectId, infra = { modules: [] }) {
|
|
44
44
|
return {
|
|
45
45
|
metadata: {
|
|
46
46
|
name: projectId,
|
package/dist/testSupport.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testSupport.js","sourceRoot":"","sources":["../src/testSupport.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppManifest } from '@ankhorage/contracts';\nimport { promises as fs } from 'fs';\nimport os from 'os';\nimport path from 'path';\n\nimport type { InfraCommandContext } from './commandContext.js';\n\nexport interface CapturedCommandContext {\n readonly context: InfraCommandContext;\n readonly stderr: { value: string };\n readonly stdout: { value: string };\n}\n\nexport function createCapturedCommandContext(\n cwd: string,\n version = '0.2.1',\n): CapturedCommandContext {\n const stdout = { value: '' };\n const stderr = { value: '' };\n\n return {\n stdout,\n stderr,\n context: {\n cwd,\n env: process.env,\n version,\n writeStdout(text: string) {\n stdout.value += text;\n },\n writeStderr(text: string) {\n stderr.value += text;\n },\n },\n };\n}\n\nexport async function createWorkspaceFixture(\n args: {\n readonly manifest?: AppManifest;\n readonly manifestFile?: 'invalid-json' | 'missing';\n readonly projectId?: string;\n } = {},\n): Promise<{\n readonly appsRoot: string;\n readonly projectId: string;\n readonly projectPath: string;\n readonly rootPath: string;\n}> {\n const rootPath = await fs.mkdtemp(path.join(os.tmpdir(), 'ankhorage-infra-'));\n const appsRoot = path.join(rootPath, 'apps');\n const projectId = args.projectId ?? 'shop';\n const projectPath = path.join(appsRoot, projectId);\n\n await fs.mkdir(projectPath, { recursive: true });\n await fs.writeFile(\n path.join(projectPath, 'package.json'),\n JSON.stringify({ name: projectId, version: '1.0.0' }, null, 2),\n 'utf8',\n );\n\n if (args.manifestFile === 'invalid-json') {\n await fs.writeFile(path.join(projectPath, 'ankh.config.json'), '{invalid', 'utf8');\n } else if (args.manifestFile !== 'missing') {\n await fs.writeFile(\n path.join(projectPath, 'ankh.config.json'),\n `${JSON.stringify(args.manifest ?? createAppManifest(projectId), null, 2)}\\n`,\n 'utf8',\n );\n }\n\n return {\n appsRoot,\n projectId,\n projectPath,\n rootPath,\n };\n}\n\nexport function createAppManifest(\n projectId: string,\n infra: AppManifest['infra'] = {
|
|
1
|
+
{"version":3,"file":"testSupport.js","sourceRoot":"","sources":["../src/testSupport.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppManifest } from '@ankhorage/contracts';\nimport { promises as fs } from 'fs';\nimport os from 'os';\nimport path from 'path';\n\nimport type { InfraCommandContext } from './commandContext.js';\n\nexport interface CapturedCommandContext {\n readonly context: InfraCommandContext;\n readonly stderr: { value: string };\n readonly stdout: { value: string };\n}\n\nexport function createCapturedCommandContext(\n cwd: string,\n version = '0.2.1',\n): CapturedCommandContext {\n const stdout = { value: '' };\n const stderr = { value: '' };\n\n return {\n stdout,\n stderr,\n context: {\n cwd,\n env: process.env,\n version,\n writeStdout(text: string) {\n stdout.value += text;\n },\n writeStderr(text: string) {\n stderr.value += text;\n },\n },\n };\n}\n\nexport async function createWorkspaceFixture(\n args: {\n readonly manifest?: AppManifest;\n readonly manifestFile?: 'invalid-json' | 'missing';\n readonly projectId?: string;\n } = {},\n): Promise<{\n readonly appsRoot: string;\n readonly projectId: string;\n readonly projectPath: string;\n readonly rootPath: string;\n}> {\n const rootPath = await fs.mkdtemp(path.join(os.tmpdir(), 'ankhorage-infra-'));\n const appsRoot = path.join(rootPath, 'apps');\n const projectId = args.projectId ?? 'shop';\n const projectPath = path.join(appsRoot, projectId);\n\n await fs.mkdir(projectPath, { recursive: true });\n await fs.writeFile(\n path.join(projectPath, 'package.json'),\n JSON.stringify({ name: projectId, version: '1.0.0' }, null, 2),\n 'utf8',\n );\n\n if (args.manifestFile === 'invalid-json') {\n await fs.writeFile(path.join(projectPath, 'ankh.config.json'), '{invalid', 'utf8');\n } else if (args.manifestFile !== 'missing') {\n await fs.writeFile(\n path.join(projectPath, 'ankh.config.json'),\n `${JSON.stringify(args.manifest ?? createAppManifest(projectId), null, 2)}\\n`,\n 'utf8',\n );\n }\n\n return {\n appsRoot,\n projectId,\n projectPath,\n rootPath,\n };\n}\n\nexport function createAppManifest(\n projectId: string,\n infra: AppManifest['infra'] = { modules: [] },\n): AppManifest {\n return {\n metadata: {\n name: projectId,\n slug: projectId,\n version: '1.0.0',\n category: 'developer_tools',\n themeId: 'default',\n },\n themes: [],\n activeThemeId: 'default',\n infra,\n navigator: {\n type: 'stack',\n routes: [{ name: 'index', screenId: 'index' }],\n },\n screens: {},\n settings: {\n localization: {\n defaultLocale: 'en',\n locales: ['en'],\n },\n },\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/infra",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.0",
|
|
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": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"openapi"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ankhorage/contracts": "^
|
|
38
|
+
"@ankhorage/contracts": "^6.0.0",
|
|
39
39
|
"@ankhorage/supabase-vault": "^0.2.4"
|
|
40
40
|
},
|
|
41
41
|
"files": [
|
|
@@ -21,7 +21,7 @@ test('keeps multiple provider redirect assignments as separate shell arguments',
|
|
|
21
21
|
},
|
|
22
22
|
database: { provider: 'supabase', tier: 'dev' },
|
|
23
23
|
secretStore: { provider: 'supabase-vault' },
|
|
24
|
-
|
|
24
|
+
modules: [],
|
|
25
25
|
};
|
|
26
26
|
const result = generateInfrastructure(manifest, {
|
|
27
27
|
appManifest: createAppManifest('multi-oauth'),
|
|
@@ -33,7 +33,7 @@ test('re-exports rotated public environment values before building the app image
|
|
|
33
33
|
{
|
|
34
34
|
deployment: { target: 'minikube', monitoring: false },
|
|
35
35
|
auth: { scope: 'global', provider: 'supabase' },
|
|
36
|
-
|
|
36
|
+
modules: [],
|
|
37
37
|
},
|
|
38
38
|
{ appManifest: createAppManifest(APP_SLUG) },
|
|
39
39
|
);
|
|
@@ -101,7 +101,7 @@ describe('generateMinikubeBaseArtifacts app-owned cluster model', () => {
|
|
|
101
101
|
target: 'minikube',
|
|
102
102
|
monitoring: false,
|
|
103
103
|
},
|
|
104
|
-
|
|
104
|
+
modules: [],
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
appManifest: createAppManifest('frontend-only'),
|
|
@@ -508,7 +508,7 @@ function createSupabaseManifest(): InfraManifestInput {
|
|
|
508
508
|
provider: 'supabase',
|
|
509
509
|
buckets: ['assets'],
|
|
510
510
|
},
|
|
511
|
-
|
|
511
|
+
modules: [],
|
|
512
512
|
};
|
|
513
513
|
}
|
|
514
514
|
|
|
@@ -140,7 +140,7 @@ function generateAppOnlyInfrastructure(slug: string) {
|
|
|
140
140
|
target: 'minikube',
|
|
141
141
|
monitoring: false,
|
|
142
142
|
},
|
|
143
|
-
|
|
143
|
+
modules: [],
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
return generateInfrastructure(manifest, {
|
|
@@ -280,7 +280,7 @@ function generateSupabaseInfrastructure(slug: string) {
|
|
|
280
280
|
secretStore: {
|
|
281
281
|
provider: 'supabase-vault',
|
|
282
282
|
},
|
|
283
|
-
|
|
283
|
+
modules: [],
|
|
284
284
|
};
|
|
285
285
|
|
|
286
286
|
return generateInfrastructure(manifest, {
|
package/src/commands.test.ts
CHANGED
|
@@ -66,7 +66,7 @@ describe('infra command table', () => {
|
|
|
66
66
|
manifestPath: '/workspace/apps/shop/ankh.config.json',
|
|
67
67
|
projectId: 'shop',
|
|
68
68
|
projectPath: '/workspace/apps/shop',
|
|
69
|
-
manifest: createAppManifest('shop', {
|
|
69
|
+
manifest: createAppManifest('shop', { modules: [] }),
|
|
70
70
|
});
|
|
71
71
|
},
|
|
72
72
|
validateInfraSupport() {
|
|
@@ -104,7 +104,7 @@ describe('infra command table', () => {
|
|
|
104
104
|
manifestPath: '/workspace/apps/studio/ankh.config.json',
|
|
105
105
|
projectId: 'studio',
|
|
106
106
|
projectPath: '/workspace/apps/studio',
|
|
107
|
-
manifest: createAppManifest('studio', {
|
|
107
|
+
manifest: createAppManifest('studio', { modules: [] }),
|
|
108
108
|
});
|
|
109
109
|
},
|
|
110
110
|
syncProjectInfrastructure() {
|
|
@@ -146,7 +146,7 @@ describe('infra command table', () => {
|
|
|
146
146
|
projectPath: '/workspace/apps/shop',
|
|
147
147
|
manifest: createAppManifest('shop', {
|
|
148
148
|
deployment: { target: 'minikube', monitoring: false },
|
|
149
|
-
|
|
149
|
+
modules: [],
|
|
150
150
|
}),
|
|
151
151
|
});
|
|
152
152
|
},
|
|
@@ -327,7 +327,7 @@ describe('generated API database bridge', () => {
|
|
|
327
327
|
const infra: InfraManifestInput = {
|
|
328
328
|
deployment: { target: 'minikube', monitoring: false },
|
|
329
329
|
database: { provider: 'supabase', tier: 'dev' },
|
|
330
|
-
|
|
330
|
+
modules: [],
|
|
331
331
|
};
|
|
332
332
|
const appManifest = {
|
|
333
333
|
...createAppManifest('catalog', infra),
|
package/src/index.test.ts
CHANGED
|
@@ -42,7 +42,7 @@ describe('generateInfrastructure', () => {
|
|
|
42
42
|
domain: 'alpha.local',
|
|
43
43
|
cdn: false,
|
|
44
44
|
},
|
|
45
|
-
|
|
45
|
+
modules: [],
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
const result = generateInfrastructure(manifest, { appManifest: createAppManifest('alpha') });
|
|
@@ -125,7 +125,7 @@ describe('generateInfrastructure', () => {
|
|
|
125
125
|
provider: 'supabase',
|
|
126
126
|
buckets: ['assets', ' assets ', '', 'assets', 'uploads'],
|
|
127
127
|
},
|
|
128
|
-
|
|
128
|
+
modules: [],
|
|
129
129
|
};
|
|
130
130
|
|
|
131
131
|
const result = generateInfrastructure(manifest, {
|
|
@@ -163,7 +163,7 @@ describe('generateInfrastructure', () => {
|
|
|
163
163
|
provider: 'supabase',
|
|
164
164
|
tier: 'dev',
|
|
165
165
|
},
|
|
166
|
-
|
|
166
|
+
modules: [],
|
|
167
167
|
};
|
|
168
168
|
|
|
169
169
|
const appManifest: Pick<AppManifest, 'metadata' | 'navigator' | 'screens' | 'settings'> = {
|
|
@@ -237,7 +237,7 @@ describe('generateInfrastructure', () => {
|
|
|
237
237
|
|
|
238
238
|
test('throws for missing deployment', () => {
|
|
239
239
|
const manifest: InfraManifestInput = {
|
|
240
|
-
|
|
240
|
+
modules: [],
|
|
241
241
|
};
|
|
242
242
|
|
|
243
243
|
expect(() => generateInfrastructure(manifest)).toThrow('Deployment configuration is missing.');
|
|
@@ -249,7 +249,7 @@ describe('generateInfrastructure', () => {
|
|
|
249
249
|
target: 'kubernetes',
|
|
250
250
|
monitoring: false,
|
|
251
251
|
},
|
|
252
|
-
|
|
252
|
+
modules: [],
|
|
253
253
|
};
|
|
254
254
|
|
|
255
255
|
expect(() => generateInfrastructure(manifest)).toThrow(
|
|
@@ -267,7 +267,7 @@ describe('generateInfrastructure', () => {
|
|
|
267
267
|
provider: 'supabase',
|
|
268
268
|
tier: 'dev',
|
|
269
269
|
},
|
|
270
|
-
|
|
270
|
+
modules: [],
|
|
271
271
|
};
|
|
272
272
|
|
|
273
273
|
expect(() => generateInfrastructure(manifest, { namespaceHint: 'shop' })).toThrow(
|
package/src/project.test.ts
CHANGED
|
@@ -58,7 +58,7 @@ describe('resolveInfraProject', () => {
|
|
|
58
58
|
|
|
59
59
|
expect(project.manifest.metadata.name).toBe('shop');
|
|
60
60
|
expect(project.manifest.metadata.slug).toBe('shop');
|
|
61
|
-
expect(project.manifest.infra.
|
|
61
|
+
expect(project.manifest.infra.modules).toEqual([]);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
test('rejects malformed manifest JSON', async () => {
|
|
@@ -186,7 +186,7 @@ describe('resolveInfraProject', () => {
|
|
|
186
186
|
monitoring: false,
|
|
187
187
|
target: 'minikube',
|
|
188
188
|
},
|
|
189
|
-
|
|
189
|
+
modules: [],
|
|
190
190
|
});
|
|
191
191
|
const fixture = await createWorkspaceFixture({
|
|
192
192
|
manifest,
|
package/src/project.ts
CHANGED
|
@@ -76,7 +76,7 @@ function createFallbackManifest(projectId: string): AppManifest {
|
|
|
76
76
|
themes: [],
|
|
77
77
|
activeThemeId: 'default',
|
|
78
78
|
infra: {
|
|
79
|
-
|
|
79
|
+
modules: [],
|
|
80
80
|
},
|
|
81
81
|
navigator: {
|
|
82
82
|
type: 'stack',
|
|
@@ -196,7 +196,7 @@ function isAppManifestMetadata(value: unknown): value is AppManifest['metadata']
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
function isInfraManifestRecord(value: unknown): value is AppManifest['infra'] {
|
|
199
|
-
return isRecord(value) && Array.isArray(value.
|
|
199
|
+
return isRecord(value) && Array.isArray(value.modules);
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
function isNavigatorSpec(value: unknown): value is NavigatorSpec {
|
|
@@ -29,7 +29,7 @@ describe('project infrastructure sync', () => {
|
|
|
29
29
|
projectPath,
|
|
30
30
|
manifest: createAppManifest('shop', {
|
|
31
31
|
deployment: { target: 'minikube', monitoring: false },
|
|
32
|
-
|
|
32
|
+
modules: [],
|
|
33
33
|
}),
|
|
34
34
|
generateInfrastructureImpl() {
|
|
35
35
|
return {
|
|
@@ -77,7 +77,7 @@ describe('project infrastructure sync', () => {
|
|
|
77
77
|
|
|
78
78
|
const manifest = createAppManifest('shop', {
|
|
79
79
|
deployment: { target: 'minikube', monitoring: false },
|
|
80
|
-
|
|
80
|
+
modules: [],
|
|
81
81
|
});
|
|
82
82
|
|
|
83
83
|
await syncProjectInfrastructure({
|
|
@@ -141,7 +141,7 @@ describe('project infrastructure sync', () => {
|
|
|
141
141
|
const result = await syncProjectInfrastructure({
|
|
142
142
|
projectId: 'shop',
|
|
143
143
|
projectPath,
|
|
144
|
-
manifest: createAppManifest('shop', {
|
|
144
|
+
manifest: createAppManifest('shop', { modules: [] }),
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
expect(result.generated).toBe(0);
|
|
@@ -158,7 +158,7 @@ describe('project infrastructure sync', () => {
|
|
|
158
158
|
projectPath,
|
|
159
159
|
manifest: createAppManifest('studio', {
|
|
160
160
|
deployment: { target: 'minikube', monitoring: false },
|
|
161
|
-
|
|
161
|
+
modules: [],
|
|
162
162
|
}),
|
|
163
163
|
});
|
|
164
164
|
|
|
@@ -183,7 +183,7 @@ describe('project infrastructure sync', () => {
|
|
|
183
183
|
);
|
|
184
184
|
|
|
185
185
|
const target = await resolveProjectInfrastructureTarget({
|
|
186
|
-
manifest: createAppManifest('shop', {
|
|
186
|
+
manifest: createAppManifest('shop', { modules: [] }),
|
|
187
187
|
projectPath,
|
|
188
188
|
});
|
|
189
189
|
|
package/src/testSupport.ts
CHANGED