@ankhorage/studio 0.11.8 → 0.11.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/host/auth/projectAuthHealthService.d.ts +3 -1
- package/dist/host/auth/projectAuthHealthService.d.ts.map +1 -1
- package/dist/host/auth/projectAuthHealthService.js +49 -9
- package/dist/host/auth/projectAuthHealthService.js.map +1 -1
- package/dist/host/auth/projectAuthRuntimeDiagnostics.d.ts +28 -0
- package/dist/host/auth/projectAuthRuntimeDiagnostics.d.ts.map +1 -0
- package/dist/host/auth/projectAuthRuntimeDiagnostics.js +192 -0
- package/dist/host/auth/projectAuthRuntimeDiagnostics.js.map +1 -0
- package/dist/host/http/authRoutes.d.ts.map +1 -1
- package/dist/host/http/authRoutes.js +1 -0
- package/dist/host/http/authRoutes.js.map +1 -1
- package/dist/host/layout/templates/auth/callback.d.ts.map +1 -1
- package/dist/host/layout/templates/auth/callback.js +30 -11
- package/dist/host/layout/templates/auth/callback.js.map +1 -1
- package/dist/host/layout/templates/auth/oauth.d.ts.map +1 -1
- package/dist/host/layout/templates/auth/oauth.js +63 -8
- package/dist/host/layout/templates/auth/oauth.js.map +1 -1
- package/dist/projectAuthRuntimeDiagnostics.d.ts +11 -0
- package/dist/projectAuthRuntimeDiagnostics.d.ts.map +1 -0
- package/dist/projectAuthRuntimeDiagnostics.js +97 -0
- package/dist/projectAuthRuntimeDiagnostics.js.map +1 -0
- package/package.json +2 -2
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { ProjectAuthHealth } from '../../projectAuthHealth';
|
|
2
2
|
import type { ProjectManager } from '../orchestrator/projectManager';
|
|
3
3
|
import type { ProjectSecretService } from '../secrets/projectSecretService';
|
|
4
|
-
type ProjectAuthHealthManager = Pick<ProjectManager, 'getProjectManifest' | 'getStudioManifest'>;
|
|
4
|
+
type ProjectAuthHealthManager = Pick<ProjectManager, 'getInfrastructureStatus' | 'getProjectManifest' | 'getStudioManifest'>;
|
|
5
5
|
export declare class ProjectAuthHealthService {
|
|
6
6
|
private readonly projectManager;
|
|
7
7
|
private readonly secretService;
|
|
8
|
+
private readonly workspaceRoot;
|
|
8
9
|
constructor(options: {
|
|
9
10
|
readonly projectManager: ProjectAuthHealthManager;
|
|
10
11
|
readonly secretService: Pick<ProjectSecretService, 'list'>;
|
|
12
|
+
readonly workspaceRoot: string;
|
|
11
13
|
});
|
|
12
14
|
get(input: {
|
|
13
15
|
readonly projectId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectAuthHealthService.d.ts","sourceRoot":"","sources":["../../../src/host/auth/projectAuthHealthService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"projectAuthHealthService.d.ts","sourceRoot":"","sources":["../../../src/host/auth/projectAuthHealthService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAG5E,KAAK,wBAAwB,GAAG,IAAI,CAClC,cAAc,EACd,yBAAyB,GAAG,oBAAoB,GAAG,mBAAmB,CACvE,CAAC;AAEF,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2B;IAC1D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqC;IACnE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAE3B,OAAO,EAAE;QACnB,QAAQ,CAAC,cAAc,EAAE,wBAAwB,CAAC;QAClD,QAAQ,CAAC,aAAa,EAAE,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;QAC3D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;KAChC;IAMK,GAAG,CAAC,KAAK,EAAE;QACf,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;KAC/B,GAAG,OAAO,CAAC,uBAAuB,CAAC;YA8DtB,oBAAoB;CAOnC;AAOD,MAAM,MAAM,uBAAuB,GAC/B;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;CAClC,GACD;IACE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;QACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH,CAAC"}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { analyzeProjectAuthHealth } from '../../projectAuthHealth';
|
|
2
|
+
import { applyProjectAuthRuntimeDiagnostics } from '../../projectAuthRuntimeDiagnostics';
|
|
3
|
+
import { observeProjectAuthRuntimeDiagnostics } from './projectAuthRuntimeDiagnostics';
|
|
2
4
|
export class ProjectAuthHealthService {
|
|
3
5
|
projectManager;
|
|
4
6
|
secretService;
|
|
7
|
+
workspaceRoot;
|
|
5
8
|
constructor(options) {
|
|
6
9
|
this.projectManager = options.projectManager;
|
|
7
10
|
this.secretService = options.secretService;
|
|
11
|
+
this.workspaceRoot = options.workspaceRoot;
|
|
8
12
|
}
|
|
9
13
|
async get(input) {
|
|
10
14
|
let manifest;
|
|
@@ -24,15 +28,46 @@ export class ProjectAuthHealthService {
|
|
|
24
28
|
projectId: input.projectId,
|
|
25
29
|
environment: input.environment,
|
|
26
30
|
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
const desiredHealth = analyzeProjectAuthHealth({
|
|
32
|
+
manifest,
|
|
33
|
+
secretMetadata: secretResult.ok ? secretResult.data : [],
|
|
34
|
+
secretStoreAvailable: secretResult.ok,
|
|
35
|
+
});
|
|
36
|
+
const oauth = manifest.infra.auth?.oauth;
|
|
37
|
+
if (!oauth?.enabled || !oauth.providers.some((provider) => provider.enabled === true)) {
|
|
38
|
+
return {
|
|
39
|
+
ok: true,
|
|
40
|
+
state: 'loaded',
|
|
41
|
+
data: desiredHealth,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const infraStatus = await this.projectManager.getInfrastructureStatus(input.projectId);
|
|
46
|
+
const runtimeDiagnostics = await observeProjectAuthRuntimeDiagnostics({
|
|
47
|
+
rootPath: this.workspaceRoot,
|
|
48
|
+
projectId: input.projectId,
|
|
49
|
+
target: infraStatus.target,
|
|
50
|
+
generated: infraStatus.hasLedger,
|
|
51
|
+
environment: resolveAuthRedirectEnvironment(input.environment),
|
|
52
|
+
callbackRoute: oauth.callbackRoute,
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
ok: true,
|
|
56
|
+
state: 'loaded',
|
|
57
|
+
data: applyProjectAuthRuntimeDiagnostics(desiredHealth, runtimeDiagnostics),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return {
|
|
62
|
+
ok: true,
|
|
63
|
+
state: 'loaded',
|
|
64
|
+
data: applyProjectAuthRuntimeDiagnostics(desiredHealth, {
|
|
65
|
+
appCallbackTargets: [],
|
|
66
|
+
redirectAllowList: [],
|
|
67
|
+
rolloutStatus: 'unavailable',
|
|
68
|
+
}),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
36
71
|
}
|
|
37
72
|
async readEditableManifest(projectId) {
|
|
38
73
|
try {
|
|
@@ -43,4 +78,9 @@ export class ProjectAuthHealthService {
|
|
|
43
78
|
}
|
|
44
79
|
}
|
|
45
80
|
}
|
|
81
|
+
function resolveAuthRedirectEnvironment(environment) {
|
|
82
|
+
if (environment === 'preview' || environment === 'production')
|
|
83
|
+
return environment;
|
|
84
|
+
return 'local';
|
|
85
|
+
}
|
|
46
86
|
//# sourceMappingURL=projectAuthHealthService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectAuthHealthService.js","sourceRoot":"","sources":["../../../src/host/auth/projectAuthHealthService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"projectAuthHealthService.js","sourceRoot":"","sources":["../../../src/host/auth/projectAuthHealthService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AuthRedirectEnvironment } from '@ankhorage/infra';
|
|
2
|
+
import type { ProjectAuthRuntimeDiagnostics, ProjectAuthRuntimeRolloutStatus } from '../../projectAuthRuntimeDiagnostics';
|
|
3
|
+
export interface ProjectAuthRedirectRuntime {
|
|
4
|
+
readonly providerRedirectUrl: string;
|
|
5
|
+
readonly siteUrl: string;
|
|
6
|
+
readonly appCallbackTargets: readonly string[];
|
|
7
|
+
readonly redirectAllowList: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
export interface ParsedProjectAuthRuntimeStatus {
|
|
10
|
+
readonly rolloutStatus: ProjectAuthRuntimeRolloutStatus;
|
|
11
|
+
readonly providerRedirectUrl?: string;
|
|
12
|
+
readonly appCallbackUrl?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function observeProjectAuthRuntimeDiagnostics(input: {
|
|
15
|
+
readonly rootPath: string;
|
|
16
|
+
readonly projectId: string;
|
|
17
|
+
readonly target: string | null;
|
|
18
|
+
readonly generated: boolean;
|
|
19
|
+
readonly environment: AuthRedirectEnvironment;
|
|
20
|
+
readonly callbackRoute: string;
|
|
21
|
+
}): Promise<ProjectAuthRuntimeDiagnostics>;
|
|
22
|
+
export declare function resolveProjectAuthRedirectRuntime(input: {
|
|
23
|
+
readonly environment: AuthRedirectEnvironment;
|
|
24
|
+
readonly callbackRoute: string;
|
|
25
|
+
readonly infraEnvironment: Readonly<Record<string, string | undefined>>;
|
|
26
|
+
}): ProjectAuthRedirectRuntime;
|
|
27
|
+
export declare function parseProjectAuthRuntimeStatus(stdout: string): ParsedProjectAuthRuntimeStatus;
|
|
28
|
+
//# sourceMappingURL=projectAuthRuntimeDiagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectAuthRuntimeDiagnostics.d.ts","sourceRoot":"","sources":["../../../src/host/auth/projectAuthRuntimeDiagnostics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAIhE,OAAO,KAAK,EACV,6BAA6B,EAC7B,+BAA+B,EAChC,MAAM,qCAAqC,CAAC;AAa7C,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,aAAa,EAAE,+BAA+B,CAAC;IACxD,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,wBAAsB,oCAAoC,CAAC,KAAK,EAAE;IAChE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,uBAAuB,CAAC;IAC9C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAmFzC;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE;IACvD,QAAQ,CAAC,WAAW,EAAE,uBAAuB,CAAC;IAC9C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;CACzE,GAAG,0BAA0B,CA+B7B;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,GAAG,8BAA8B,CAiB5F"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { resolveAuthRedirectConfiguration } from '@ankhorage/infra';
|
|
4
|
+
import { runProjectInfraScriptCapture } from '../orchestrator/infraRuntime';
|
|
5
|
+
import { getProjectPath } from '../orchestrator/projectPaths';
|
|
6
|
+
const SAFE_INFRA_ENV_KEYS = new Set([
|
|
7
|
+
'API_EXTERNAL_URL',
|
|
8
|
+
'APP_PORT_FORWARD_LOCAL_PORT',
|
|
9
|
+
'EXPO_PUBLIC_SUPABASE_URL',
|
|
10
|
+
'OAUTH_NATIVE_REDIRECT_URLS',
|
|
11
|
+
'SITE_URL',
|
|
12
|
+
'SUPABASE_GATEWAY_FORWARD_LOCAL_PORT',
|
|
13
|
+
]);
|
|
14
|
+
export async function observeProjectAuthRuntimeDiagnostics(input) {
|
|
15
|
+
if (!input.generated || !input.target) {
|
|
16
|
+
return {
|
|
17
|
+
appCallbackTargets: [],
|
|
18
|
+
redirectAllowList: [],
|
|
19
|
+
rolloutStatus: 'not-generated',
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const diagnostics = [];
|
|
23
|
+
let expected = null;
|
|
24
|
+
try {
|
|
25
|
+
const environment = await readSafeGeneratedInfraEnvironment({
|
|
26
|
+
rootPath: input.rootPath,
|
|
27
|
+
projectId: input.projectId,
|
|
28
|
+
target: input.target,
|
|
29
|
+
});
|
|
30
|
+
expected = resolveProjectAuthRedirectRuntime({
|
|
31
|
+
environment: input.environment,
|
|
32
|
+
callbackRoute: input.callbackRoute,
|
|
33
|
+
infraEnvironment: environment,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
diagnostics.push({
|
|
38
|
+
code: 'auth_redirect_configuration_unavailable',
|
|
39
|
+
severity: 'warning',
|
|
40
|
+
message: 'Canonical Auth callback diagnostics could not be derived from generated Infra.',
|
|
41
|
+
path: 'infra.auth.oauth',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
let observed = { rolloutStatus: 'unavailable' };
|
|
45
|
+
try {
|
|
46
|
+
const status = await runProjectInfraScriptCapture({
|
|
47
|
+
rootPath: input.rootPath,
|
|
48
|
+
projectId: input.projectId,
|
|
49
|
+
target: input.target,
|
|
50
|
+
script: 'status',
|
|
51
|
+
});
|
|
52
|
+
observed = parseProjectAuthRuntimeStatus(status.stdout);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// The public health result deliberately reports only a bounded state, never script output.
|
|
56
|
+
}
|
|
57
|
+
if (expected?.providerRedirectUrl &&
|
|
58
|
+
observed.providerRedirectUrl &&
|
|
59
|
+
expected.providerRedirectUrl !== observed.providerRedirectUrl) {
|
|
60
|
+
diagnostics.push({
|
|
61
|
+
code: 'auth_runtime_provider_callback_stale',
|
|
62
|
+
severity: 'error',
|
|
63
|
+
message: 'The running Auth provider callback does not match generated Infra configuration.',
|
|
64
|
+
path: 'infra.auth.oauth.providerCallback',
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const expectedAppCallbackUrl = expected?.appCallbackTargets.find(isExactWebCallbackUrl);
|
|
68
|
+
if (expectedAppCallbackUrl &&
|
|
69
|
+
observed.appCallbackUrl &&
|
|
70
|
+
expectedAppCallbackUrl !== observed.appCallbackUrl) {
|
|
71
|
+
diagnostics.push({
|
|
72
|
+
code: 'auth_runtime_app_callback_stale',
|
|
73
|
+
severity: 'error',
|
|
74
|
+
message: 'The running Auth app callback does not match generated Infra configuration.',
|
|
75
|
+
path: 'infra.auth.oauth.callbackRoute',
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
...(expected?.providerRedirectUrl
|
|
80
|
+
? { providerRedirectUrl: expected.providerRedirectUrl }
|
|
81
|
+
: observed.providerRedirectUrl
|
|
82
|
+
? { providerRedirectUrl: observed.providerRedirectUrl }
|
|
83
|
+
: {}),
|
|
84
|
+
appCallbackTargets: expected?.appCallbackTargets ?? [],
|
|
85
|
+
redirectAllowList: expected?.redirectAllowList ?? [],
|
|
86
|
+
rolloutStatus: observed.rolloutStatus,
|
|
87
|
+
diagnostics,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export function resolveProjectAuthRedirectRuntime(input) {
|
|
91
|
+
const siteOrigin = resolveOrigin(input.infraEnvironment.SITE_URL, input.infraEnvironment.APP_PORT_FORWARD_LOCAL_PORT);
|
|
92
|
+
const gatewayOrigin = resolveOrigin(input.infraEnvironment.API_EXTERNAL_URL ?? input.infraEnvironment.EXPO_PUBLIC_SUPABASE_URL, input.infraEnvironment.SUPABASE_GATEWAY_FORWARD_LOCAL_PORT);
|
|
93
|
+
if (!siteOrigin || !gatewayOrigin) {
|
|
94
|
+
throw new Error('Generated Infra does not expose canonical app and gateway origins.');
|
|
95
|
+
}
|
|
96
|
+
const configuration = resolveAuthRedirectConfiguration({
|
|
97
|
+
environment: input.environment,
|
|
98
|
+
gatewayOrigin,
|
|
99
|
+
siteOrigin,
|
|
100
|
+
callbackRoute: input.callbackRoute,
|
|
101
|
+
webOrigins: [siteOrigin],
|
|
102
|
+
nativeRedirectUris: splitCommaSeparated(input.infraEnvironment.OAUTH_NATIVE_REDIRECT_URLS),
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
providerRedirectUrl: configuration.providerCallbackUrl,
|
|
106
|
+
siteUrl: configuration.siteUrl,
|
|
107
|
+
appCallbackTargets: configuration.redirectAllowList.filter((target) => target !== configuration.siteUrl),
|
|
108
|
+
redirectAllowList: configuration.redirectAllowList,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function parseProjectAuthRuntimeStatus(stdout) {
|
|
112
|
+
const providerRedirectUrl = readSafeStatusValue(stdout, /provider\s+supabase-auth\/provider-callback:\s*([^\r\n]+)/iu);
|
|
113
|
+
const appCallbackUrl = readSafeStatusValue(stdout, /provider\s+supabase-auth\/app-callback:\s*([^\r\n]+)/iu);
|
|
114
|
+
const readiness = /provider\s+supabase-auth\/GoTrue:\s*(not ready|ready)\b/iu.exec(stdout)?.[1];
|
|
115
|
+
return {
|
|
116
|
+
rolloutStatus: readiness === 'ready' ? 'ready' : readiness === 'not ready' ? 'not-ready' : 'unavailable',
|
|
117
|
+
...(providerRedirectUrl ? { providerRedirectUrl } : {}),
|
|
118
|
+
...(appCallbackUrl ? { appCallbackUrl } : {}),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async function readSafeGeneratedInfraEnvironment(input) {
|
|
122
|
+
const projectPath = getProjectPath(input.rootPath, input.projectId);
|
|
123
|
+
const infraRoot = path.join(projectPath, 'infra', input.target);
|
|
124
|
+
const envPath = path.join(infraRoot, '.env');
|
|
125
|
+
const fallbackPath = path.join(infraRoot, '.env.example');
|
|
126
|
+
const sourcePath = (await exists(envPath)) ? envPath : fallbackPath;
|
|
127
|
+
const content = await fs.readFile(sourcePath, 'utf8');
|
|
128
|
+
const environment = {};
|
|
129
|
+
for (const line of content.split(/\r?\n/u)) {
|
|
130
|
+
const trimmed = line.trim();
|
|
131
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
132
|
+
continue;
|
|
133
|
+
const separatorIndex = trimmed.indexOf('=');
|
|
134
|
+
if (separatorIndex <= 0)
|
|
135
|
+
continue;
|
|
136
|
+
const key = trimmed.slice(0, separatorIndex).trim();
|
|
137
|
+
if (!SAFE_INFRA_ENV_KEYS.has(key))
|
|
138
|
+
continue;
|
|
139
|
+
environment[key] = trimmed
|
|
140
|
+
.slice(separatorIndex + 1)
|
|
141
|
+
.trim()
|
|
142
|
+
.replace(/^['"]|['"]$/g, '');
|
|
143
|
+
}
|
|
144
|
+
return environment;
|
|
145
|
+
}
|
|
146
|
+
function resolveOrigin(value, portValue) {
|
|
147
|
+
if (value?.trim()) {
|
|
148
|
+
try {
|
|
149
|
+
return new URL(value.trim()).origin;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const port = parsePort(portValue);
|
|
156
|
+
return port === null ? null : `http://127.0.0.1:${port}`;
|
|
157
|
+
}
|
|
158
|
+
function parsePort(value) {
|
|
159
|
+
if (!value)
|
|
160
|
+
return null;
|
|
161
|
+
const port = Number.parseInt(value, 10);
|
|
162
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535)
|
|
163
|
+
return null;
|
|
164
|
+
return port;
|
|
165
|
+
}
|
|
166
|
+
function splitCommaSeparated(value) {
|
|
167
|
+
if (!value)
|
|
168
|
+
return [];
|
|
169
|
+
return value
|
|
170
|
+
.split(',')
|
|
171
|
+
.map((entry) => entry.trim())
|
|
172
|
+
.filter(Boolean);
|
|
173
|
+
}
|
|
174
|
+
function readSafeStatusValue(stdout, pattern) {
|
|
175
|
+
const value = pattern.exec(stdout)?.[1]?.trim();
|
|
176
|
+
if (!value || value.length > 2048 || /\s/u.test(value))
|
|
177
|
+
return undefined;
|
|
178
|
+
return value;
|
|
179
|
+
}
|
|
180
|
+
function isExactWebCallbackUrl(value) {
|
|
181
|
+
return /^https?:\/\//u.test(value) && !value.includes('*');
|
|
182
|
+
}
|
|
183
|
+
async function exists(filePath) {
|
|
184
|
+
try {
|
|
185
|
+
await fs.access(filePath);
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=projectAuthRuntimeDiagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectAuthRuntimeDiagnostics.js","sourceRoot":"","sources":["../../../src/host/auth/projectAuthRuntimeDiagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,gCAAgC,EAAE,MAAM,kBAAkB,CAAC;AAOpE,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,kBAAkB;IAClB,6BAA6B;IAC7B,0BAA0B;IAC1B,4BAA4B;IAC5B,UAAU;IACV,qCAAqC;CACtC,CAAC,CAAC;AAeH,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAO1D;IACC,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO;YACL,kBAAkB,EAAE,EAAE;YACtB,iBAAiB,EAAE,EAAE;YACrB,aAAa,EAAE,eAAe;SAC/B,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAA4B,EAAE,CAAC;IAChD,IAAI,QAAQ,GAAsC,IAAI,CAAC;IAEvD,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,iCAAiC,CAAC;YAC1D,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;SACrB,CAAC,CAAC;QACH,QAAQ,GAAG,iCAAiC,CAAC;YAC3C,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,gBAAgB,EAAE,WAAW;SAC9B,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,yCAAyC;YAC/C,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,gFAAgF;YACzF,IAAI,EAAE,kBAAkB;SACzB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,QAAQ,GAAmC,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;IAChF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC;YAChD,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QACH,QAAQ,GAAG,6BAA6B,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,2FAA2F;IAC7F,CAAC;IAED,IACE,QAAQ,EAAE,mBAAmB;QAC7B,QAAQ,CAAC,mBAAmB;QAC5B,QAAQ,CAAC,mBAAmB,KAAK,QAAQ,CAAC,mBAAmB,EAC7D,CAAC;QACD,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,sCAAsC;YAC5C,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,kFAAkF;YAC3F,IAAI,EAAE,mCAAmC;SAC1C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,sBAAsB,GAAG,QAAQ,EAAE,kBAAkB,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACxF,IACE,sBAAsB;QACtB,QAAQ,CAAC,cAAc;QACvB,sBAAsB,KAAK,QAAQ,CAAC,cAAc,EAClD,CAAC;QACD,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,iCAAiC;YACvC,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,6EAA6E;YACtF,IAAI,EAAE,gCAAgC;SACvC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,GAAG,CAAC,QAAQ,EAAE,mBAAmB;YAC/B,CAAC,CAAC,EAAE,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,EAAE;YACvD,CAAC,CAAC,QAAQ,CAAC,mBAAmB;gBAC5B,CAAC,CAAC,EAAE,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,EAAE;gBACvD,CAAC,CAAC,EAAE,CAAC;QACT,kBAAkB,EAAE,QAAQ,EAAE,kBAAkB,IAAI,EAAE;QACtD,iBAAiB,EAAE,QAAQ,EAAE,iBAAiB,IAAI,EAAE;QACpD,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,KAIjD;IACC,MAAM,UAAU,GAAG,aAAa,CAC9B,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAC/B,KAAK,CAAC,gBAAgB,CAAC,2BAA2B,CACnD,CAAC;IACF,MAAM,aAAa,GAAG,aAAa,CACjC,KAAK,CAAC,gBAAgB,CAAC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB,CAAC,wBAAwB,EAC1F,KAAK,CAAC,gBAAgB,CAAC,mCAAmC,CAC3D,CAAC;IAEF,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,aAAa,GAAG,gCAAgC,CAAC;QACrD,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,aAAa;QACb,UAAU;QACV,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,UAAU,EAAE,CAAC,UAAU,CAAC;QACxB,kBAAkB,EAAE,mBAAmB,CAAC,KAAK,CAAC,gBAAgB,CAAC,0BAA0B,CAAC;KAC3F,CAAC,CAAC;IAEH,OAAO;QACL,mBAAmB,EAAE,aAAa,CAAC,mBAAmB;QACtD,OAAO,EAAE,aAAa,CAAC,OAAO;QAC9B,kBAAkB,EAAE,aAAa,CAAC,iBAAiB,CAAC,MAAM,CACxD,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,aAAa,CAAC,OAAO,CAC7C;QACD,iBAAiB,EAAE,aAAa,CAAC,iBAAiB;KACnD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,MAAc;IAC1D,MAAM,mBAAmB,GAAG,mBAAmB,CAC7C,MAAM,EACN,6DAA6D,CAC9D,CAAC;IACF,MAAM,cAAc,GAAG,mBAAmB,CACxC,MAAM,EACN,wDAAwD,CACzD,CAAC;IACF,MAAM,SAAS,GAAG,2DAA2D,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEhG,OAAO;QACL,aAAa,EACX,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa;QAC3F,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iCAAiC,CAAC,KAIhD;IACC,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAC1D,MAAM,UAAU,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;IACpE,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACtD,MAAM,WAAW,GAA2B,EAAE,CAAC;IAE/C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAClD,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5C,IAAI,cAAc,IAAI,CAAC;YAAE,SAAS;QAClC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,IAAI,EAAE,CAAC;QACpD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5C,WAAW,CAAC,GAAG,CAAC,GAAG,OAAO;aACvB,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;aACzB,IAAI,EAAE;aACN,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,aAAa,CAAC,KAAyB,EAAE,SAA6B;IAC7E,IAAI,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QAClB,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,IAAI,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,SAAS,CAAC,KAAyB;IAC1C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK;QAAE,OAAO,IAAI,CAAC;IACrE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAyB;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,OAAO,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAc,EAAE,OAAe;IAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzE,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa;IAC1C,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,QAAgB;IACpC,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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authRoutes.d.ts","sourceRoot":"","sources":["../../../src/host/http/authRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAM7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGrE,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;IAAE,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACpF,IAAI,
|
|
1
|
+
{"version":3,"file":"authRoutes.d.ts","sourceRoot":"","sources":["../../../src/host/http/authRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAM7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGrE,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;IAAE,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACpF,IAAI,CA+BN"}
|
|
@@ -5,6 +5,7 @@ export function registerProjectAuthRoutes(fastify, options) {
|
|
|
5
5
|
? null
|
|
6
6
|
: new ProjectAuthHealthService({
|
|
7
7
|
projectManager: options.projectManager,
|
|
8
|
+
workspaceRoot: options.workspaceRoot,
|
|
8
9
|
secretService: new ProjectSecretService({
|
|
9
10
|
projectManager: options.projectManager,
|
|
10
11
|
workspaceRoot: options.workspaceRoot,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authRoutes.js","sourceRoot":"","sources":["../../../src/host/http/authRoutes.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,wBAAwB,GACzB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,MAAM,UAAU,yBAAyB,CACvC,OAAwB,EACxB,OAAqF;IAErF,MAAM,aAAa,GACjB,OAAO,CAAC,aAAa,KAAK,SAAS;QACjC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,wBAAwB,CAAC;YAC3B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,aAAa,EAAE,IAAI,oBAAoB,CAAC;gBACtC,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,aAAa,EAAE,OAAO,CAAC,aAAa;aACrC,CAAC;SACH,CAAC,CAAC;IAET,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,KAAK,EAAE,OAAuB,EAAE,KAAK,EAAE,EAAE;QACpF,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAwB,CAAC;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAiC,CAAC;QACxD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC5B,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,0BAA0B;oBAChC,OAAO,EAAE,2DAA2D;iBACrE;aACF,CAAC,CAAC;QACL,CAAC;QAED,OAAO,2BAA2B,CAChC,KAAK,EACL,MAAM,aAAa,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAC3E,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAmB,EAAE,MAA+B;IACvF,IAAI,MAAM,CAAC,EAAE;QAAE,OAAO,MAAM,CAAC;IAE7B,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC"}
|
|
1
|
+
{"version":3,"file":"authRoutes.js","sourceRoot":"","sources":["../../../src/host/http/authRoutes.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,wBAAwB,GACzB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAEvE,MAAM,UAAU,yBAAyB,CACvC,OAAwB,EACxB,OAAqF;IAErF,MAAM,aAAa,GACjB,OAAO,CAAC,aAAa,KAAK,SAAS;QACjC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,wBAAwB,CAAC;YAC3B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,aAAa,EAAE,IAAI,oBAAoB,CAAC;gBACtC,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,aAAa,EAAE,OAAO,CAAC,aAAa;aACrC,CAAC;SACH,CAAC,CAAC;IAET,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,KAAK,EAAE,OAAuB,EAAE,KAAK,EAAE,EAAE;QACpF,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,MAAwB,CAAC;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAiC,CAAC;QACxD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC5B,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,0BAA0B;oBAChC,OAAO,EAAE,2DAA2D;iBACrE;aACF,CAAC,CAAC;QACL,CAAC;QAED,OAAO,2BAA2B,CAChC,KAAK,EACL,MAAM,aAAa,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAC3E,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAmB,EAAE,MAA+B;IACvF,IAAI,MAAM,CAAC,EAAE;QAAE,OAAO,MAAM,CAAC;IAE7B,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/callback.ts"],"names":[],"mappings":"AAGA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/callback.ts"],"names":[],"mappings":"AAGA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,UAkI7F"}
|
|
@@ -5,38 +5,57 @@ export function getAuthOAuthCallbackTsx(args) {
|
|
|
5
5
|
const postSignInTarget = escapeStringLiteral(routeNameToGroupedHref(args.postSignInRoute, 'app'));
|
|
6
6
|
return `import * as Linking from 'expo-linking';
|
|
7
7
|
import { Stack, useRouter } from 'expo-router';
|
|
8
|
-
import * as WebBrowser from 'expo-web-browser';
|
|
9
8
|
import { useEffect, useRef, useState } from 'react';
|
|
10
|
-
import { ActivityIndicator,
|
|
9
|
+
import { ActivityIndicator, Pressable, StyleSheet, View } from 'react-native';
|
|
11
10
|
import { Text, useZoraTheme } from '@ankhorage/zora';
|
|
12
11
|
|
|
13
12
|
import { completeOAuthCallback } from '@/auth/oauth';
|
|
14
13
|
|
|
15
14
|
const SIGN_IN_ROUTE = '${signInTarget}';
|
|
16
15
|
const POST_SIGN_IN_ROUTE = '${postSignInTarget}';
|
|
17
|
-
const webBrowserCompletion =
|
|
18
|
-
Platform.OS === 'web' ? WebBrowser.maybeCompleteAuthSession() : null;
|
|
19
16
|
const callbackScreenOptions = { title: 'Completing sign in' };
|
|
20
17
|
|
|
18
|
+
interface ActiveCallbackCompletion {
|
|
19
|
+
callbackUrl: string;
|
|
20
|
+
promise: ReturnType<typeof completeOAuthCallback>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let activeCallbackCompletion: ActiveCallbackCompletion | null = null;
|
|
24
|
+
|
|
25
|
+
function completeOAuthCallbackOnce(callbackUrl: string) {
|
|
26
|
+
if (!activeCallbackCompletion || activeCallbackCompletion.callbackUrl !== callbackUrl) {
|
|
27
|
+
activeCallbackCompletion = {
|
|
28
|
+
callbackUrl,
|
|
29
|
+
promise: completeOAuthCallback(callbackUrl),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return activeCallbackCompletion.promise;
|
|
33
|
+
}
|
|
34
|
+
|
|
21
35
|
export default function OAuthCallbackScreen() {
|
|
22
36
|
const router = useRouter();
|
|
23
37
|
const callbackUrl = Linking.useURL();
|
|
24
38
|
const { theme } = useZoraTheme();
|
|
25
|
-
const
|
|
39
|
+
const handledOutcomeRef = useRef(false);
|
|
26
40
|
const [message, setMessage] = useState('Completing secure sign in…');
|
|
27
41
|
const [failed, setFailed] = useState(false);
|
|
28
42
|
|
|
29
43
|
useEffect(() => {
|
|
30
|
-
if (webBrowserCompletion?.type === 'success' || handledRef.current) return;
|
|
31
|
-
|
|
32
44
|
let active = true;
|
|
33
45
|
void (async () => {
|
|
34
46
|
const deliveredUrl = callbackUrl ?? (await Linking.getInitialURL());
|
|
35
|
-
if (!deliveredUrl
|
|
36
|
-
|
|
47
|
+
if (!deliveredUrl) {
|
|
48
|
+
if (active && !handledOutcomeRef.current) {
|
|
49
|
+
handledOutcomeRef.current = true;
|
|
50
|
+
setFailed(true);
|
|
51
|
+
setMessage('The OAuth callback URL is unavailable.');
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
37
55
|
|
|
38
|
-
const outcome = await
|
|
39
|
-
if (!active) return;
|
|
56
|
+
const outcome = await completeOAuthCallbackOnce(deliveredUrl);
|
|
57
|
+
if (!active || handledOutcomeRef.current) return;
|
|
58
|
+
handledOutcomeRef.current = true;
|
|
40
59
|
|
|
41
60
|
if (outcome.status === 'authenticated') {
|
|
42
61
|
router.replace(POST_SIGN_IN_ROUTE);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,UAAU,uBAAuB,CAAC,IAAsD;IAC5F,MAAM,YAAY,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3F,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC;IAElG,OAAO
|
|
1
|
+
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,UAAU,uBAAuB,CAAC,IAAsD;IAC5F,MAAM,YAAY,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3F,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,sBAAsB,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC;IAElG,OAAO;;;;;;;;yBAQgB,YAAY;8BACP,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoH7C,CAAC;AACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAG5E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAG5E,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,mBAAmB,UAoU9D"}
|
|
@@ -70,7 +70,17 @@ async function runOAuthAuthorization(
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
let redirectUri: string;
|
|
74
|
+
try {
|
|
75
|
+
redirectUri = resolveOAuthRedirectUri();
|
|
76
|
+
} catch {
|
|
77
|
+
return {
|
|
78
|
+
status: 'error',
|
|
79
|
+
message: 'The OAuth redirect URI could not be resolved in this environment.',
|
|
80
|
+
recoverable: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
74
84
|
const started = await oauth.startAuthorization({
|
|
75
85
|
provider: provider.id,
|
|
76
86
|
redirectUri,
|
|
@@ -101,6 +111,13 @@ async function runOAuthAuthorization(
|
|
|
101
111
|
};
|
|
102
112
|
}
|
|
103
113
|
|
|
114
|
+
if (Platform.OS === 'web') {
|
|
115
|
+
return redirectWebAuthorization({
|
|
116
|
+
attemptId: started.data.attemptId,
|
|
117
|
+
authorizationUrl: started.data.authorizationUrl,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
104
121
|
let browserResult: WebBrowser.WebBrowserAuthSessionResult;
|
|
105
122
|
try {
|
|
106
123
|
browserResult = await WebBrowser.openAuthSessionAsync(
|
|
@@ -131,6 +148,42 @@ async function runOAuthAuthorization(
|
|
|
131
148
|
return toTransportOutcome(completed);
|
|
132
149
|
}
|
|
133
150
|
|
|
151
|
+
async function redirectWebAuthorization(args: {
|
|
152
|
+
attemptId: string;
|
|
153
|
+
authorizationUrl: string;
|
|
154
|
+
}): Promise<GeneratedOAuthTransportOutcome> {
|
|
155
|
+
const location = getBrowserLocation();
|
|
156
|
+
const assign = location ? Reflect.get(location, 'assign') : undefined;
|
|
157
|
+
if (typeof assign !== 'function') {
|
|
158
|
+
await cancelOAuthAttempt(args.attemptId, 'browser_dismissed');
|
|
159
|
+
await clearTransportAttempt();
|
|
160
|
+
return {
|
|
161
|
+
status: 'error',
|
|
162
|
+
message: 'Web OAuth requires full-page browser navigation.',
|
|
163
|
+
recoverable: true,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
Reflect.apply(assign, location, [args.authorizationUrl]);
|
|
169
|
+
return waitForFullPageNavigation();
|
|
170
|
+
} catch {
|
|
171
|
+
await cancelOAuthAttempt(args.attemptId, 'browser_dismissed');
|
|
172
|
+
await clearTransportAttempt();
|
|
173
|
+
return {
|
|
174
|
+
status: 'error',
|
|
175
|
+
message: 'The browser could not navigate to the OAuth provider.',
|
|
176
|
+
recoverable: true,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function waitForFullPageNavigation(): Promise<never> {
|
|
182
|
+
return new Promise<never>(() => {
|
|
183
|
+
// Full-page navigation replaces this document before the promise settles.
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
134
187
|
export async function completeOAuthCallback(
|
|
135
188
|
callbackUrl: string,
|
|
136
189
|
): Promise<GeneratedOAuthTransportOutcome> {
|
|
@@ -176,13 +229,10 @@ function resolveOAuthRedirectUri(): string {
|
|
|
176
229
|
callbackPath = callbackPath.slice(1);
|
|
177
230
|
}
|
|
178
231
|
if (Platform.OS === 'web') {
|
|
179
|
-
const location =
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
typeof Reflect.get(location, 'origin') === 'string'
|
|
184
|
-
) {
|
|
185
|
-
return new URL(\`/\${callbackPath}\`, Reflect.get(location, 'origin')).toString();
|
|
232
|
+
const location = getBrowserLocation();
|
|
233
|
+
const origin = location ? Reflect.get(location, 'origin') : undefined;
|
|
234
|
+
if (typeof origin === 'string' && origin.length > 0) {
|
|
235
|
+
return new URL(\`/\${callbackPath}\`, origin).toString();
|
|
186
236
|
}
|
|
187
237
|
throw new Error('Web OAuth requires a canonical browser origin.');
|
|
188
238
|
}
|
|
@@ -190,6 +240,11 @@ function resolveOAuthRedirectUri(): string {
|
|
|
190
240
|
return Linking.createURL(callbackPath);
|
|
191
241
|
}
|
|
192
242
|
|
|
243
|
+
function getBrowserLocation(): object | null {
|
|
244
|
+
const location = Reflect.get(globalThis, 'location');
|
|
245
|
+
return typeof location === 'object' && location !== null ? location : null;
|
|
246
|
+
}
|
|
247
|
+
|
|
193
248
|
function toTransportOutcome(
|
|
194
249
|
result: AuthOAuthCompletionResult,
|
|
195
250
|
): GeneratedOAuthTransportOutcome {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/oauth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,UAAU,qBAAqB,CAAC,IAAyB;IAC7D,MAAM,aAAa,GAAG,mBAAmB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEjD,OAAO;;;;;;;;;;;;;;;gCAeuB,aAAa;;oCAET,SAAS
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../../../../src/host/layout/templates/auth/oauth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,MAAM,UAAU,qBAAqB,CAAC,IAAyB;IAC7D,MAAM,aAAa,GAAG,mBAAmB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAEjD,OAAO;;;;;;;;;;;;;;;gCAeuB,aAAa;;oCAET,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8S5C,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProjectAuthDiagnostic, ProjectAuthHealth } from './projectAuthHealth';
|
|
2
|
+
export type ProjectAuthRuntimeRolloutStatus = 'ready' | 'not-ready' | 'unavailable' | 'not-generated';
|
|
3
|
+
export interface ProjectAuthRuntimeDiagnostics {
|
|
4
|
+
readonly providerRedirectUrl?: string;
|
|
5
|
+
readonly appCallbackTargets: readonly string[];
|
|
6
|
+
readonly redirectAllowList: readonly string[];
|
|
7
|
+
readonly rolloutStatus: ProjectAuthRuntimeRolloutStatus;
|
|
8
|
+
readonly diagnostics?: readonly ProjectAuthDiagnostic[];
|
|
9
|
+
}
|
|
10
|
+
export declare function applyProjectAuthRuntimeDiagnostics(health: ProjectAuthHealth, runtime: ProjectAuthRuntimeDiagnostics): ProjectAuthHealth;
|
|
11
|
+
//# sourceMappingURL=projectAuthRuntimeDiagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectAuthRuntimeDiagnostics.d.ts","sourceRoot":"","sources":["../src/projectAuthRuntimeDiagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EAErB,iBAAiB,EAElB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,+BAA+B,GACzC,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,eAAe,CAAC;AAE1D,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9C,QAAQ,CAAC,aAAa,EAAE,+BAA+B,CAAC;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACzD;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,6BAA6B,GACrC,iBAAiB,CA6BnB"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export function applyProjectAuthRuntimeDiagnostics(health, runtime) {
|
|
2
|
+
const diagnostics = [
|
|
3
|
+
...health.diagnostics,
|
|
4
|
+
...runtime.appCallbackTargets.map((target, index) => ({
|
|
5
|
+
code: 'app_callback_target',
|
|
6
|
+
severity: 'info',
|
|
7
|
+
message: `Enabled app callback target: ${target}`,
|
|
8
|
+
path: `infra.auth.oauth.callbackTargets[${index}]`,
|
|
9
|
+
})),
|
|
10
|
+
...runtime.redirectAllowList.map((target, index) => ({
|
|
11
|
+
code: 'redirect_allow_list_entry',
|
|
12
|
+
severity: 'info',
|
|
13
|
+
message: `Auth redirect allowlist entry: ${target}`,
|
|
14
|
+
path: `infra.auth.oauth.redirectAllowList[${index}]`,
|
|
15
|
+
})),
|
|
16
|
+
resolveRolloutDiagnostic(runtime.rolloutStatus),
|
|
17
|
+
...(runtime.diagnostics ?? []),
|
|
18
|
+
];
|
|
19
|
+
const sortedDiagnostics = sortDiagnostics(uniqueDiagnostics(diagnostics));
|
|
20
|
+
return {
|
|
21
|
+
...health,
|
|
22
|
+
status: resolveHealthStatus(sortedDiagnostics),
|
|
23
|
+
diagnostics: sortedDiagnostics,
|
|
24
|
+
callbackUrls: {
|
|
25
|
+
...health.callbackUrls,
|
|
26
|
+
...(runtime.providerRedirectUrl ? { providerRedirectUrl: runtime.providerRedirectUrl } : {}),
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function resolveRolloutDiagnostic(status) {
|
|
31
|
+
switch (status) {
|
|
32
|
+
case 'ready':
|
|
33
|
+
return {
|
|
34
|
+
code: 'auth_runtime_ready',
|
|
35
|
+
severity: 'info',
|
|
36
|
+
message: 'The running Auth deployment reports ready.',
|
|
37
|
+
path: 'infra.auth.runtime',
|
|
38
|
+
};
|
|
39
|
+
case 'not-ready':
|
|
40
|
+
return {
|
|
41
|
+
code: 'auth_runtime_not_ready',
|
|
42
|
+
severity: 'error',
|
|
43
|
+
message: 'The running Auth deployment is not ready.',
|
|
44
|
+
path: 'infra.auth.runtime',
|
|
45
|
+
};
|
|
46
|
+
case 'not-generated':
|
|
47
|
+
return {
|
|
48
|
+
code: 'auth_runtime_not_generated',
|
|
49
|
+
severity: 'warning',
|
|
50
|
+
message: 'Auth runtime diagnostics are unavailable until infrastructure is generated.',
|
|
51
|
+
path: 'infra.auth.runtime',
|
|
52
|
+
};
|
|
53
|
+
case 'unavailable':
|
|
54
|
+
return {
|
|
55
|
+
code: 'auth_runtime_unavailable',
|
|
56
|
+
severity: 'warning',
|
|
57
|
+
message: 'The generated infrastructure could not report Auth runtime readiness.',
|
|
58
|
+
path: 'infra.auth.runtime',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function resolveHealthStatus(diagnostics) {
|
|
63
|
+
if (diagnostics.some((diagnostic) => diagnostic.severity === 'error'))
|
|
64
|
+
return 'error';
|
|
65
|
+
if (diagnostics.some((diagnostic) => diagnostic.severity === 'warning'))
|
|
66
|
+
return 'warning';
|
|
67
|
+
return 'healthy';
|
|
68
|
+
}
|
|
69
|
+
function sortDiagnostics(diagnostics) {
|
|
70
|
+
const severityRank = {
|
|
71
|
+
error: 0,
|
|
72
|
+
warning: 1,
|
|
73
|
+
info: 2,
|
|
74
|
+
};
|
|
75
|
+
return [...diagnostics].sort((left, right) => severityRank[left.severity] - severityRank[right.severity] ||
|
|
76
|
+
left.code.localeCompare(right.code) ||
|
|
77
|
+
(left.path ?? '').localeCompare(right.path ?? '') ||
|
|
78
|
+
(left.providerId ?? '').localeCompare(right.providerId ?? ''));
|
|
79
|
+
}
|
|
80
|
+
function uniqueDiagnostics(diagnostics) {
|
|
81
|
+
const seen = new Set();
|
|
82
|
+
return diagnostics.filter((diagnostic) => {
|
|
83
|
+
const key = [
|
|
84
|
+
diagnostic.code,
|
|
85
|
+
diagnostic.severity,
|
|
86
|
+
diagnostic.message,
|
|
87
|
+
diagnostic.path ?? '',
|
|
88
|
+
diagnostic.providerId ?? '',
|
|
89
|
+
diagnostic.credentialsRef ?? '',
|
|
90
|
+
].join('\u0000');
|
|
91
|
+
if (seen.has(key))
|
|
92
|
+
return false;
|
|
93
|
+
seen.add(key);
|
|
94
|
+
return true;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=projectAuthRuntimeDiagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectAuthRuntimeDiagnostics.js","sourceRoot":"","sources":["../src/projectAuthRuntimeDiagnostics.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/studio",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.10",
|
|
4
4
|
"description": "Studio authoring package for Ankhorage apps",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/studio#readme",
|
|
@@ -231,7 +231,7 @@
|
|
|
231
231
|
"@ankhorage/color-theory": "^0.0.8",
|
|
232
232
|
"@ankhorage/contracts": "^4.0.1",
|
|
233
233
|
"@ankhorage/expo-runtime": "^0.0.11",
|
|
234
|
-
"@ankhorage/infra": "^1.0
|
|
234
|
+
"@ankhorage/infra": "^1.1.0",
|
|
235
235
|
"@ankhorage/orchestrator": "^0.2.4",
|
|
236
236
|
"@ankhorage/orchestrator-module-expo-google-fonts": "^0.1.2",
|
|
237
237
|
"@ankhorage/orchestrator-module-expo-localization": "^0.1.5",
|