@astrale-os/cli 1.0.0-beta.3 → 1.0.0-beta.30
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/README.md +80 -6
- package/dist/astrale.js +55471 -58674
- package/dist/public/connect-core.js +2158 -30706
- package/dist/public/keys/index.js +1016 -29541
- package/dist/public/paths/index.js +370 -28654
- package/dist/types/admin/contract.d.ts +26 -0
- package/dist/types/admin/instance/client.d.ts +20 -0
- package/dist/types/admin/instance/index.d.ts +2 -0
- package/dist/types/admin/instance/model.d.ts +6 -10
- package/dist/types/connection/auth.d.ts +3 -0
- package/dist/types/connection/call.d.ts +3 -0
- package/dist/types/connection/command.d.ts +27 -0
- package/dist/types/connection/credential.d.ts +14 -0
- package/dist/types/connection/errors.d.ts +1 -0
- package/dist/types/connection/exchange.d.ts +9 -0
- package/dist/types/connection/failure/classify.d.ts +2 -0
- package/dist/types/connection/failure/index.d.ts +5 -0
- package/dist/types/connection/failure/model.d.ts +25 -0
- package/dist/types/connection/failure/render.d.ts +3 -0
- package/dist/types/connection/index.d.ts +8 -0
- package/dist/types/connection/reasons.d.ts +37 -0
- package/dist/types/connection/self.d.ts +37 -0
- package/dist/types/connection/session.d.ts +31 -0
- package/dist/types/connection/target.d.ts +38 -0
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/lib/admin-instance.d.ts +17 -0
- package/dist/types/lib/admin-target.d.ts +11 -36
- package/dist/types/lib/config.d.ts +13 -59
- package/dist/types/lib/failure-debug.d.ts +1 -0
- package/dist/types/lib/idp.d.ts +25 -173
- package/dist/types/lib/instance-target.d.ts +1 -1
- package/dist/types/lib/instance.d.ts +30 -88
- package/dist/types/lib/log.d.ts +5 -3
- package/dist/types/lib/output.d.ts +1 -1
- package/dist/types/lib/proc.d.ts +43 -0
- package/dist/types/lib/self.d.ts +9 -0
- package/dist/types/lib/update.d.ts +109 -0
- package/dist/types/lib/validation.d.ts +4 -1
- package/dist/types/state/exchange-credentials.d.ts +6 -2
- package/dist/types/state/files.d.ts +2 -0
- package/dist/types/state/index.d.ts +3 -2
- package/dist/types/state/paths.d.ts +2 -0
- package/dist/types/state/session-routes.d.ts +10 -0
- package/package.json +16 -19
- package/src/__tests__/fixtures/publication.ts +20 -0
- package/src/admin/.spec/architecture.md +12 -5
- package/src/admin/__tests__/fixture.ts +25 -0
- package/src/admin/catalog/.spec/api.d.ts +1 -3
- package/src/admin/catalog/.spec/architecture.md +5 -4
- package/src/admin/catalog/__tests__/client.test.ts +143 -69
- package/src/admin/catalog/client.ts +40 -54
- package/src/admin/catalog/model.ts +3 -4
- package/src/admin/contract.ts +47 -0
- package/src/admin/graph/.spec/api.d.ts +4 -10
- package/src/admin/graph/nodes.ts +1 -1
- package/src/admin/instance/.spec/api.d.ts +5 -9
- package/src/admin/instance/.spec/architecture.md +7 -7
- package/src/admin/instance/__tests__/client.test.ts +157 -175
- package/src/admin/instance/client.ts +39 -128
- package/src/admin/instance/index.ts +1 -2
- package/src/admin/instance/model.ts +12 -18
- package/src/commands/__tests__/admin-instance.test.ts +11 -8
- package/src/commands/__tests__/call-describe.test.ts +46 -33
- package/src/commands/__tests__/call.test.ts +34 -0
- package/src/commands/__tests__/domain-install-operation.test.ts +30 -22
- package/src/commands/__tests__/domain-install-owned.test.ts +1 -1
- package/src/commands/__tests__/domain-list.test.ts +5 -25
- package/src/commands/__tests__/install-direct.test.ts +115 -8
- package/src/commands/__tests__/install-identity-override.test.ts +6 -17
- package/src/commands/__tests__/instance-list-rows.test.ts +1 -1
- package/src/commands/__tests__/instance-status.test.ts +139 -0
- package/src/commands/__tests__/introspect-parse.test.ts +80 -1
- package/src/commands/__tests__/logs.test.ts +250 -2
- package/src/commands/__tests__/read-commands.test.ts +118 -10
- package/src/commands/__tests__/token-ttl.test.ts +49 -4
- package/src/commands/__tests__/update.test.ts +25 -3
- package/src/commands/__tests__/view.test.ts +50 -2
- package/src/commands/auth/logout.ts +2 -1
- package/src/commands/browser.ts +29 -0
- package/src/commands/call-describe.ts +60 -68
- package/src/commands/call.ts +71 -59
- package/src/commands/domain/install.ts +73 -46
- package/src/commands/domain/list.ts +1 -1
- package/src/commands/domain/publish.ts +14 -11
- package/src/commands/domain/uninstall.ts +2 -2
- package/src/commands/get.ts +15 -16
- package/src/commands/identity/__tests__/register.test.ts +3 -3
- package/src/commands/identity/register.ts +8 -8
- package/src/commands/instance/create.ts +8 -16
- package/src/commands/instance/delete.ts +12 -9
- package/src/commands/instance/list.ts +2 -2
- package/src/commands/instance/status.ts +66 -20
- package/src/commands/instance/use.ts +16 -12
- package/src/commands/introspect.ts +53 -41
- package/src/commands/logs.ts +123 -36
- package/src/commands/mutate.ts +6 -5
- package/src/commands/query.ts +35 -32
- package/src/commands/session/analyze.ts +26 -4
- package/src/commands/token.ts +42 -27
- package/src/commands/ui/__tests__/commands.test.ts +152 -0
- package/src/commands/ui/add.ts +51 -0
- package/src/commands/ui/doctor.ts +21 -0
- package/src/commands/ui/init.ts +38 -0
- package/src/commands/ui/list.ts +26 -0
- package/src/commands/ui/preset-apply.ts +19 -0
- package/src/commands/ui/preset-list.ts +12 -0
- package/src/commands/ui/shared.ts +25 -0
- package/src/commands/update.ts +89 -48
- package/src/commands/view.ts +82 -37
- package/src/connection/.spec/api.d.ts +7 -8
- package/src/connection/.spec/architecture.md +14 -5
- package/src/connection/.spec/flows/session.ts +2 -2
- package/src/connection/.spec/laws/connection.ts +6 -2
- package/src/connection/.spec/layout.ts +1 -0
- package/src/connection/__tests__/auth.test.ts +1 -0
- package/src/connection/__tests__/credential.test.ts +21 -1
- package/src/connection/__tests__/errors.test.ts +27 -20
- package/src/connection/__tests__/exchange.test.ts +64 -11
- package/src/connection/__tests__/failure-fixtures.ts +39 -0
- package/src/connection/__tests__/failure-safety.test.ts +75 -0
- package/src/connection/__tests__/self.test.ts +31 -11
- package/src/connection/__tests__/session.test.ts +8 -4
- package/src/connection/__tests__/target.test.ts +2 -0
- package/src/connection/auth.ts +13 -0
- package/src/connection/call.ts +1 -1
- package/src/connection/credential.ts +2 -2
- package/src/connection/errors.ts +1 -355
- package/src/connection/exchange.ts +110 -61
- package/src/connection/failure/classify.ts +110 -0
- package/src/connection/failure/index.ts +18 -0
- package/src/connection/failure/model.ts +28 -0
- package/src/connection/failure/render.ts +116 -0
- package/src/connection/reasons.ts +16 -0
- package/src/connection/self.ts +39 -21
- package/src/connection/session.ts +27 -9
- package/src/errors.ts +3 -2
- package/src/graph/.spec/api.d.ts +12 -5
- package/src/graph/.spec/layout.ts +9 -1
- package/src/graph/__tests__/mutation.test.ts +2 -2
- package/src/graph/__tests__/query.test.ts +25 -6
- package/src/graph/class.ts +30 -0
- package/src/graph/index.ts +1 -0
- package/src/graph/query.ts +21 -32
- package/src/identity/.spec/api.d.ts +2 -2
- package/src/identity/__tests__/fixtures/registry-journey.ts +13 -1
- package/src/identity/__tests__/registration.test.ts +1 -1
- package/src/identity/__tests__/registry.test.ts +4 -0
- package/src/identity/registration.ts +3 -3
- package/src/identity/registry.ts +2 -0
- package/src/keys/__tests__/keys.test.ts +4 -0
- package/src/keys/credential.ts +1 -0
- package/src/lib/__tests__/admin-target.test.ts +12 -0
- package/src/lib/__tests__/binary.test.ts +16 -1
- package/src/lib/__tests__/browser-retention.test.ts +212 -0
- package/src/lib/__tests__/command-dx.test.ts +1 -1
- package/src/lib/__tests__/config.test.ts +27 -0
- package/src/lib/__tests__/domain-publication.test.ts +10 -16
- package/src/lib/__tests__/idp.test.ts +34 -4
- package/src/lib/__tests__/instance-candidates.test.ts +1 -3
- package/src/lib/__tests__/instance-target.test.ts +7 -39
- package/src/lib/__tests__/log-errors.test.ts +64 -0
- package/src/lib/__tests__/skills.test.ts +809 -0
- package/src/lib/__tests__/studio-server-deps.test.ts +1 -1
- package/src/lib/__tests__/update.test.ts +264 -11
- package/src/lib/__tests__/view-assets.test.ts +25 -0
- package/src/lib/__tests__/view-external-open-intent.test.ts +150 -0
- package/src/lib/__tests__/view-external-open-origins.test.ts +27 -0
- package/src/lib/__tests__/view-open-intent.test.ts +0 -2
- package/src/lib/__tests__/view-server.test.ts +26 -3
- package/src/lib/__tests__/view-session.test.ts +2 -1
- package/src/lib/admin-instance.ts +14 -8
- package/src/lib/admin-target.ts +21 -2
- package/src/lib/binary.ts +22 -5
- package/src/lib/browser-retention.ts +210 -0
- package/src/lib/command-dx.ts +9 -9
- package/src/lib/config.ts +12 -1
- package/src/lib/domain-publication.ts +9 -7
- package/src/lib/failure-debug.ts +26 -0
- package/src/lib/idp.ts +34 -3
- package/src/lib/instance-candidates.ts +2 -2
- package/src/lib/instance-target.ts +3 -14
- package/src/lib/instance.ts +16 -11
- package/src/lib/log.ts +16 -9
- package/src/lib/output.ts +1 -1
- package/src/lib/proc.ts +7 -2
- package/src/lib/provision-instance.ts +34 -57
- package/src/lib/skills/lock.ts +117 -0
- package/src/lib/skills/sync.ts +814 -0
- package/src/lib/skills.ts +1 -52
- package/src/lib/update.ts +298 -45
- package/src/lib/validation.ts +2 -2
- package/src/lib/view/assets.ts +11 -2
- package/src/lib/view/external-open-intent.ts +41 -0
- package/src/lib/view/external-open-origins.ts +37 -0
- package/src/lib/view/host-capabilities.ts +17 -0
- package/src/lib/view/resolve.ts +1 -1
- package/src/lib/view/server.ts +18 -3
- package/src/lib/view/session.ts +2 -0
- package/src/program/.spec/api.d.ts +1 -0
- package/src/program/__tests__/program.test.ts +163 -6
- package/src/program/argv.ts +14 -0
- package/src/program/build.ts +26 -4
- package/src/program/command.ts +1 -0
- package/src/program/index.ts +1 -0
- package/src/program/registry.ts +2 -1
- package/src/setup/__tests__/instance-step.test.ts +27 -10
- package/src/setup/steps/instance.ts +22 -15
- package/src/setup/steps/skills.ts +40 -38
- package/src/state/.spec/api.d.ts +21 -2
- package/src/state/.spec/architecture.md +18 -4
- package/src/state/.spec/layout.ts +1 -0
- package/src/state/__tests__/exchange-credentials.test.ts +88 -42
- package/src/state/__tests__/files.test.ts +24 -1
- package/src/state/__tests__/fixtures/session-route-process.ts +93 -0
- package/src/state/__tests__/paths.test.ts +1 -0
- package/src/state/__tests__/session-routes.test.ts +138 -0
- package/src/state/exchange-credentials.ts +22 -9
- package/src/state/files.ts +41 -0
- package/src/state/index.ts +3 -1
- package/src/state/paths.ts +3 -0
- package/src/state/session-routes.ts +34 -0
- package/src/telemetry/__tests__/analyze-log.test.ts +38 -0
- package/src/telemetry/__tests__/recorder.test.ts +1 -0
- package/src/telemetry/__tests__/retention.test.ts +267 -0
- package/src/telemetry/__tests__/settings.test.ts +102 -0
- package/src/telemetry/__tests__/store-scan.test.ts +128 -0
- package/src/telemetry/__tests__/trigger.test.ts +33 -4
- package/src/telemetry/analyze.ts +24 -2
- package/src/telemetry/recorder.ts +15 -4
- package/src/telemetry/retention.ts +176 -0
- package/src/telemetry/session.ts +18 -12
- package/src/telemetry/settings.ts +64 -11
- package/src/telemetry/store.ts +92 -9
- package/src/telemetry/trigger.ts +16 -28
- package/src/ui/.spec/api.d.ts +14 -0
- package/src/ui/.spec/architecture.md +14 -0
- package/src/ui/.spec/laws.ts +50 -0
- package/src/ui/.spec/layout.ts +16 -0
- package/src/ui/__tests__/ui.test.ts +1742 -0
- package/src/ui/index.ts +13 -0
- package/src/ui/lock.ts +89 -0
- package/src/ui/model.ts +83 -0
- package/src/ui/operations.ts +1044 -0
- package/src/ui/project.ts +333 -0
- package/src/ui/release.ts +398 -0
- package/src/ui/runner.ts +18 -0
- package/studio/client/dist/assets/elk-api-DjmKsHXc.js +1 -0
- package/studio/client/dist/assets/index-BFVFs_8x.js +81 -0
- package/studio/client/dist/assets/index-DuB9iUdu.css +2 -0
- package/studio/client/dist/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
- package/studio/client/dist/assets/schema-studio--a0kX3QU.css +1 -0
- package/studio/client/dist/assets/schema-studio-DH6oEWME.js +8 -0
- package/studio/client/dist/index.html +4 -3
- package/studio/package.json +8 -14
- package/studio/server/agent/ask.test.ts +1 -1
- package/studio/server/agent/bridge/grant.test.ts +1 -1
- package/studio/server/agent/bridge/routes.test.ts +1 -1
- package/studio/server/agent/harness/claude/adapter.test.ts +15 -5
- package/studio/server/agent/harness/gateway/token.test.ts +1 -1
- package/studio/server/agent/harness/gateway/token.ts +3 -3
- package/studio/server/agent/prompts/anchors.test.ts +41 -32
- package/studio/server/agent/prompts/anchors.ts +23 -51
- package/studio/server/agent/prompts/system.test.ts +4 -4
- package/studio/server/agent/prompts/system.ts +5 -5
- package/studio/server/agent/routes.test.ts +1 -1
- package/studio/server/agent/run/coordinator.test.ts +1 -1
- package/studio/server/agent/run/preparation.ts +1 -1
- package/studio/server/api/canvas.ts +0 -1
- package/studio/server/api/context.ts +1 -1
- package/studio/server/api/deployment.ts +1 -1
- package/studio/server/api/views.ts +2 -2
- package/studio/server/api/workspace.ts +1 -1
- package/studio/server/api-agent-loadout.test.ts +1 -1
- package/studio/server/api.test.ts +1 -1
- package/studio/server/cache.test.ts +24 -18
- package/studio/server/cache.ts +10 -54
- package/studio/server/cli-consumers.test.ts +31 -3
- package/studio/server/domain.test.ts +50 -68
- package/studio/server/domain.ts +82 -63
- package/studio/server/handoff/copy.ts +2 -2
- package/studio/server/index.ts +1 -1
- package/studio/server/instances/probe.test.ts +1 -1
- package/studio/server/introspect/anatomy/views/routes.ts +46 -37
- package/studio/server/introspect/anatomy/views.ts +10 -16
- package/studio/server/introspect/anatomy-extras.test.ts +29 -56
- package/studio/server/introspect/anatomy.test.ts +22 -14
- package/studio/server/introspect/anatomy.ts +6 -9
- package/studio/server/introspect/bundle.ts +0 -3
- package/studio/server/introspect/canonical-schema.test.ts +155 -424
- package/studio/server/introspect/canonical-schema.ts +248 -601
- package/studio/server/introspect/core.ts +14 -22
- package/studio/server/introspect/diff.test.ts +21 -9
- package/studio/server/introspect/diff.ts +19 -64
- package/studio/server/introspect/extractor.ts +23 -122
- package/studio/server/introspect/overlay-tsmorph.test.ts +116 -241
- package/studio/server/introspect/overlay-tsmorph.ts +0 -1
- package/studio/server/introspect/overlay.ts +3 -51
- package/studio/server/introspect/revision.test.ts +24 -28
- package/studio/server/introspect/revision.ts +11 -22
- package/studio/server/introspect/runtime.test.ts +77 -195
- package/studio/server/introspect/runtime.ts +5 -67
- package/studio/server/introspect/schema-ir-json.test.ts +81 -0
- package/studio/server/introspect/schema-ir-json.ts +39 -69
- package/studio/server/introspect/schema-refs.test.ts +43 -88
- package/studio/server/introspect/schema-refs.ts +14 -49
- package/studio/server/introspect/source-overlay/handlers.ts +116 -636
- package/studio/server/introspect/source-overlay/kernel-calls.ts +0 -3
- package/studio/server/introspect/source-overlay/spans.ts +15 -45
- package/studio/server/lifecycle.ts +4 -1
- package/studio/server/state/baseline.test.ts +14 -9
- package/studio/server/state/baseline.ts +3 -5
- package/studio/server/state/documents.test.ts +69 -0
- package/studio/server/state/documents.ts +57 -10
- package/studio/server/state/visibility.ts +1 -5
- package/studio/server/views/model.ts +3 -3
- package/studio/server/views/target.test.ts +18 -76
- package/studio/server/views/target.ts +24 -50
- package/studio/server/watch.test.ts +11 -11
- package/studio/server/watch.ts +8 -4
- package/studio/server/workspace/updates.ts +23 -1
- package/studio/server/workspace-watch.ts +2 -2
- package/studio/shared/contracts/runtime.ts +4 -0
- package/studio/shared/contracts/schema.ts +44 -131
- package/studio/shared/contracts/surface.test.ts +15 -17
- package/studio/shared/contracts/workspace.ts +5 -11
- package/studio/shared/schema/identity.test.ts +20 -44
- package/studio/shared/schema/identity.ts +9 -24
- package/studio/tsconfig.json +2 -1
- package/tsconfig.json +1 -1
- package/viewer/dist/index.html +21 -0
- package/viewer/dist/main.js +41 -62
- package/.check-workspace.cjs +0 -40
- package/src/admin/binding.ts +0 -168
- package/src/commands/__tests__/instance-create-hosts.test.ts +0 -29
- package/studio/client/dist/assets/elk-api-lwhFo7vB.js +0 -1
- package/studio/client/dist/assets/index-B-c-smo9.js +0 -8
- package/studio/client/dist/assets/index-BckHuAWk.js +0 -81
- package/studio/client/dist/assets/index-C4aNQ6dz.css +0 -1
- package/studio/client/dist/assets/index-ChOr3yP0.css +0 -1
- package/studio/server/introspect/anatomy/views/legacy.ts +0 -232
- package/studio/server/introspect/core-extractor.ts +0 -139
- package/studio/server/introspect/overlay.test.ts +0 -72
- package/studio/server/introspect/source-overlay/annotations.ts +0 -14
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs'
|
|
2
1
|
import { join, relative } from 'node:path'
|
|
3
2
|
import { Node, type SourceFile, SyntaxKind } from 'ts-morph'
|
|
4
3
|
|
|
5
4
|
import type { ViewInfo } from '../../../../shared/types'
|
|
6
5
|
|
|
6
|
+
import { resolveApplicationEntry } from '../../../domain'
|
|
7
7
|
import { defineSchemaCalls, schemaProject } from '../schema-definition'
|
|
8
8
|
import {
|
|
9
9
|
addSource,
|
|
@@ -44,27 +44,29 @@ export function buildSchemaViewSources(root: string, schemaDirName: string): Map
|
|
|
44
44
|
return sources
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return {
|
|
47
|
+
function defaultRoute(name: string): string {
|
|
48
|
+
return `/${name
|
|
49
|
+
.replace(/([a-z0-9])([A-Z])/gu, '$1-$2')
|
|
50
|
+
.replace(/[_\s]+/gu, '-')
|
|
51
|
+
.toLowerCase()}`
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function frontendSource(input: Node, source: SourceFile): { externalOrigin?: string } {
|
|
55
|
+
const value = objectProperty(input, 'source', source)
|
|
56
|
+
if (!value || !Node.isCallExpression(value)) return {}
|
|
57
|
+
if (callName(value) !== 'external') return {}
|
|
58
|
+
const origin = literalString(value.getArguments()[0], source)
|
|
59
|
+
return origin === undefined ? {} : { externalOrigin: origin }
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
export function buildFrontendViews(
|
|
62
|
+
export function buildFrontendViews(
|
|
63
|
+
root: string,
|
|
64
|
+
canonicalViewNames: readonly string[],
|
|
65
|
+
): ViewInfo[] {
|
|
63
66
|
const project = makeProject()
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const sources = [...new Set([...listSourceFiles(join(root, 'views')), ...compositionFiles])]
|
|
67
|
+
const application = resolveApplicationEntry(root)
|
|
68
|
+
const applicationFiles = application === null ? [] : [application]
|
|
69
|
+
const sources = [...new Set([...listSourceFiles(join(root, 'views')), ...applicationFiles])]
|
|
68
70
|
.map((file) => addSource(project, file))
|
|
69
71
|
.filter((source): source is SourceFile => source !== null)
|
|
70
72
|
const views: ViewInfo[] = []
|
|
@@ -72,30 +74,37 @@ export function buildFrontendViews(root: string): ViewInfo[] {
|
|
|
72
74
|
for (const source of sources) {
|
|
73
75
|
for (const call of source.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
74
76
|
const frontendName = callName(call)
|
|
75
|
-
if (frontendName !== '
|
|
77
|
+
if (frontendName !== 'defineFrontend') continue
|
|
76
78
|
const input = objectValue(call.getArguments()[0], source)
|
|
77
79
|
if (!input) continue
|
|
78
80
|
const routes = objectValue(objectProperty(input, 'routes', source) ?? undefined, source)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
81
|
+
const declared = new Map<string, string>()
|
|
82
|
+
if (routes && Node.isObjectLiteralExpression(routes)) {
|
|
83
|
+
for (const property of routes.getProperties()) {
|
|
84
|
+
const slug = propertySlug(property)
|
|
85
|
+
const routeValue = propertyValue(property, source)
|
|
86
|
+
if (!slug || !routeValue) continue
|
|
87
|
+
const direct = literalString(routeValue, source)
|
|
88
|
+
const routeInput = objectValue(routeValue, source)
|
|
89
|
+
const path =
|
|
90
|
+
direct ??
|
|
91
|
+
(routeInput
|
|
92
|
+
? literalString(objectProperty(routeInput, 'path', source) ?? undefined, source)
|
|
93
|
+
: undefined)
|
|
94
|
+
if (path) declared.set(slug, path)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const frontend = frontendSource(input, source)
|
|
91
98
|
|
|
92
|
-
|
|
93
|
-
const
|
|
99
|
+
for (const slug of canonicalViewNames) {
|
|
100
|
+
const path = declared.get(slug) ?? defaultRoute(slug)
|
|
101
|
+
const url = frontend.externalOrigin
|
|
102
|
+
? new URL(path, `${frontend.externalOrigin}/`).toString()
|
|
103
|
+
: undefined
|
|
94
104
|
views.push({
|
|
95
105
|
slug,
|
|
96
|
-
kind:
|
|
97
|
-
...(
|
|
98
|
-
...(!href && (path || !artifact.external) ? { mount: path ?? `/ui/${slug}` } : {}),
|
|
106
|
+
kind: 'spa',
|
|
107
|
+
...(url ? { url } : { mount: path }),
|
|
99
108
|
file: relative(root, source.getFilePath()).replaceAll('\\', '/'),
|
|
100
109
|
})
|
|
101
110
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { SchemaIR, ViewInfo } from '../../../shared/types'
|
|
2
2
|
|
|
3
|
-
import { buildLegacyViews } from './views/legacy'
|
|
4
3
|
import { buildFrontendViews, buildSchemaViewSources } from './views/routes'
|
|
5
4
|
|
|
6
5
|
function mergeRoute(target: ViewInfo, incoming: ViewInfo): void {
|
|
@@ -16,7 +15,6 @@ function canonicalViewInfo(slug: string, view: NonNullable<SchemaIR['views']>[st
|
|
|
16
15
|
return {
|
|
17
16
|
slug,
|
|
18
17
|
kind: 'unknown',
|
|
19
|
-
auth: view.auth,
|
|
20
18
|
...(view.description ? { description: view.description } : {}),
|
|
21
19
|
...(targets.length === 1
|
|
22
20
|
? { viewFor: targets[0] }
|
|
@@ -29,8 +27,8 @@ function canonicalViewInfo(slug: string, view: NonNullable<SchemaIR['views']>[st
|
|
|
29
27
|
/**
|
|
30
28
|
* Join canonical View definitions with route/source metadata. Passing a
|
|
31
29
|
* canonical map (including an empty map) makes it authoritative: static routes
|
|
32
|
-
* cannot invent Views or override identity, target,
|
|
33
|
-
* Without
|
|
30
|
+
* cannot invent Views or override identity, target, or description.
|
|
31
|
+
* Without admitted canonical Views, Studio does not invent authoring semantics.
|
|
34
32
|
*/
|
|
35
33
|
export function buildViews(
|
|
36
34
|
root: string,
|
|
@@ -38,21 +36,17 @@ export function buildViews(
|
|
|
38
36
|
canonicalViews?: NonNullable<SchemaIR['views']>,
|
|
39
37
|
): ViewInfo[] {
|
|
40
38
|
const merged = new Map<string, ViewInfo>()
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
for (const [slug, file] of buildSchemaViewSources(root, _schemaDirName)) {
|
|
46
|
-
const current = merged.get(slug)
|
|
47
|
-
if (current) current.file = file
|
|
48
|
-
}
|
|
49
|
-
} else {
|
|
50
|
-
for (const view of buildLegacyViews(root)) merged.set(view.slug, view)
|
|
39
|
+
const admittedViews = canonicalViews ?? {}
|
|
40
|
+
for (const [slug, view] of Object.entries(admittedViews)) {
|
|
41
|
+
merged.set(slug, canonicalViewInfo(slug, view))
|
|
51
42
|
}
|
|
52
|
-
for (const
|
|
43
|
+
for (const [slug, file] of buildSchemaViewSources(root, _schemaDirName)) {
|
|
44
|
+
const current = merged.get(slug)
|
|
45
|
+
if (current) current.file = file
|
|
46
|
+
}
|
|
47
|
+
for (const view of buildFrontendViews(root, Object.keys(admittedViews))) {
|
|
53
48
|
const current = merged.get(view.slug)
|
|
54
49
|
if (current) mergeRoute(current, view)
|
|
55
|
-
else if (canonicalViews === undefined) merged.set(view.slug, view)
|
|
56
50
|
}
|
|
57
51
|
return [...merged.values()]
|
|
58
52
|
}
|
|
@@ -46,7 +46,7 @@ test('reads the discovered client directory', () => {
|
|
|
46
46
|
})
|
|
47
47
|
})
|
|
48
48
|
|
|
49
|
-
test('
|
|
49
|
+
test('does not treat a removed view registry as Schema authority', () => {
|
|
50
50
|
const root = mkdtempSync(join(tmpdir(), 'studio-inline-view-registry-'))
|
|
51
51
|
roots.push(root)
|
|
52
52
|
const viewsDir = join(root, 'views')
|
|
@@ -55,12 +55,10 @@ test('resolves views declared in the registry file itself', () => {
|
|
|
55
55
|
join(viewsDir, 'index.ts'),
|
|
56
56
|
`import { defineView } from '@astrale-os/sdk'
|
|
57
57
|
const services = defineView({
|
|
58
|
-
auth: 'required',
|
|
59
58
|
mount: '/ui/services',
|
|
60
59
|
description: 'Browse services.',
|
|
61
60
|
})
|
|
62
61
|
const service = defineView({
|
|
63
|
-
auth: 'required',
|
|
64
62
|
mount: '/ui/service',
|
|
65
63
|
viewFor: [selfOf(CloudflareWorker)],
|
|
66
64
|
})
|
|
@@ -68,29 +66,10 @@ export const views = { services, service }
|
|
|
68
66
|
`,
|
|
69
67
|
)
|
|
70
68
|
|
|
71
|
-
expect(buildViews(root)).toEqual([
|
|
72
|
-
{
|
|
73
|
-
slug: 'services',
|
|
74
|
-
kind: 'spa',
|
|
75
|
-
url: undefined,
|
|
76
|
-
file: 'views/index.ts',
|
|
77
|
-
auth: 'required',
|
|
78
|
-
mount: '/ui/services',
|
|
79
|
-
description: 'Browse services.',
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
slug: 'service',
|
|
83
|
-
kind: 'spa',
|
|
84
|
-
url: undefined,
|
|
85
|
-
file: 'views/index.ts',
|
|
86
|
-
auth: 'required',
|
|
87
|
-
mount: '/ui/service',
|
|
88
|
-
viewFor: 'CloudflareWorker',
|
|
89
|
-
},
|
|
90
|
-
])
|
|
69
|
+
expect(buildViews(root)).toEqual([])
|
|
91
70
|
})
|
|
92
71
|
|
|
93
|
-
test('joins canonical Bundle Views with
|
|
72
|
+
test('joins canonical Bundle Views with defineFrontend route metadata', () => {
|
|
94
73
|
const root = mkdtempSync(join(tmpdir(), 'studio-current-react-view-'))
|
|
95
74
|
roots.push(root)
|
|
96
75
|
mkdirSync(join(root, 'schema', 'application'), { recursive: true })
|
|
@@ -108,7 +87,6 @@ const schemaInput = {
|
|
|
108
87
|
views: {
|
|
109
88
|
issue: view({
|
|
110
89
|
target: [Issue, Group],
|
|
111
|
-
auth: 'optional',
|
|
112
90
|
description: 'Inspect an issue.',
|
|
113
91
|
}),
|
|
114
92
|
},
|
|
@@ -118,11 +96,13 @@ export const schema = defineSchema(ORIGIN, schemaInput)
|
|
|
118
96
|
)
|
|
119
97
|
writeFileSync(
|
|
120
98
|
join(root, 'views', 'routes.ts'),
|
|
121
|
-
`import {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
99
|
+
`import { defineFrontend, vite } from '@astrale-os/sdk/application'
|
|
100
|
+
export const frontend = defineFrontend({
|
|
101
|
+
schema,
|
|
102
|
+
source: vite(),
|
|
103
|
+
routes: { issue: '/ui/issues/:id' },
|
|
104
|
+
entrypoint: 'issue',
|
|
105
|
+
})
|
|
126
106
|
`,
|
|
127
107
|
)
|
|
128
108
|
|
|
@@ -131,13 +111,12 @@ export const frontend = reactFrontend({ schema, routes, entrypoint: 'issue' })
|
|
|
131
111
|
buildViews(root, 'schema', {
|
|
132
112
|
issue: {
|
|
133
113
|
name: 'issue',
|
|
134
|
-
auth: 'optional',
|
|
135
114
|
description: 'Inspect an issue.',
|
|
136
115
|
target: {
|
|
137
116
|
kind: 'definition',
|
|
138
117
|
definitions: [
|
|
139
118
|
{ origin: 'issues.example.dev', kind: 'class', name: 'Issue' },
|
|
140
|
-
{ origin: 'accounts.example.dev', kind: '
|
|
119
|
+
{ origin: 'accounts.example.dev', kind: 'class', name: 'Group' },
|
|
141
120
|
],
|
|
142
121
|
},
|
|
143
122
|
},
|
|
@@ -146,7 +125,6 @@ export const frontend = reactFrontend({ schema, routes, entrypoint: 'issue' })
|
|
|
146
125
|
{
|
|
147
126
|
slug: 'issue',
|
|
148
127
|
kind: 'spa',
|
|
149
|
-
auth: 'optional',
|
|
150
128
|
mount: '/ui/issues/:id',
|
|
151
129
|
url: undefined,
|
|
152
130
|
viewFor: ['Issue', 'Group'],
|
|
@@ -156,7 +134,7 @@ export const frontend = reactFrontend({ schema, routes, entrypoint: 'issue' })
|
|
|
156
134
|
])
|
|
157
135
|
})
|
|
158
136
|
|
|
159
|
-
test('discovers
|
|
137
|
+
test('discovers Vite frontend default routes from canonical View names', () => {
|
|
160
138
|
const root = mkdtempSync(join(tmpdir(), 'studio-current-generated-view-'))
|
|
161
139
|
roots.push(root)
|
|
162
140
|
mkdirSync(join(root, 'schema'), { recursive: true })
|
|
@@ -170,11 +148,10 @@ test('discovers generated frontend routes without deriving canonical View defaul
|
|
|
170
148
|
)
|
|
171
149
|
writeFileSync(
|
|
172
150
|
join(root, 'views', 'summary', 'index.ts'),
|
|
173
|
-
`const source =
|
|
174
|
-
export const frontend =
|
|
151
|
+
`const source = vite()
|
|
152
|
+
export const frontend = defineFrontend({
|
|
175
153
|
schema,
|
|
176
154
|
source,
|
|
177
|
-
routes: { summary: frontendRoute({}) },
|
|
178
155
|
entrypoint: 'summary',
|
|
179
156
|
})
|
|
180
157
|
`,
|
|
@@ -184,16 +161,14 @@ export const frontend = frontendArtifact({
|
|
|
184
161
|
buildViews(root, 'schema', {
|
|
185
162
|
summary: {
|
|
186
163
|
name: 'summary',
|
|
187
|
-
auth: 'required',
|
|
188
164
|
target: { kind: 'domain' },
|
|
189
165
|
},
|
|
190
166
|
}),
|
|
191
167
|
).toEqual([
|
|
192
168
|
{
|
|
193
169
|
slug: 'summary',
|
|
194
|
-
kind: '
|
|
195
|
-
|
|
196
|
-
mount: '/ui/summary',
|
|
170
|
+
kind: 'spa',
|
|
171
|
+
mount: '/summary',
|
|
197
172
|
url: undefined,
|
|
198
173
|
file: 'views/summary/index.ts',
|
|
199
174
|
},
|
|
@@ -208,19 +183,20 @@ test('canonical Bundle views reject static schema and route-only identities', ()
|
|
|
208
183
|
join(root, 'schema', 'index.ts'),
|
|
209
184
|
`export const schema = defineSchema('static.invalid', {
|
|
210
185
|
views: {
|
|
211
|
-
account: view({ target: WrongTarget,
|
|
212
|
-
sourceOnly: view({ target: WrongTarget,
|
|
213
|
-
invented: view({ target: 'domain'
|
|
186
|
+
account: view({ target: WrongTarget, description: 'Static guess.' }),
|
|
187
|
+
sourceOnly: view({ target: WrongTarget, description: 'Static guess.' }),
|
|
188
|
+
invented: view({ target: 'domain' }),
|
|
214
189
|
},
|
|
215
190
|
})`,
|
|
216
191
|
)
|
|
217
192
|
writeFileSync(
|
|
218
|
-
join(root, '
|
|
219
|
-
`export const frontend =
|
|
220
|
-
|
|
193
|
+
join(root, 'application.ts'),
|
|
194
|
+
`export const frontend = defineFrontend({
|
|
195
|
+
schema,
|
|
196
|
+
source: external('https://shell.example.dev'),
|
|
221
197
|
routes: {
|
|
222
|
-
account:
|
|
223
|
-
routeOnly:
|
|
198
|
+
account: '/account',
|
|
199
|
+
routeOnly: '/route-only',
|
|
224
200
|
},
|
|
225
201
|
})`,
|
|
226
202
|
)
|
|
@@ -229,7 +205,6 @@ test('canonical Bundle views reject static schema and route-only identities', ()
|
|
|
229
205
|
buildViews(root, 'schema', {
|
|
230
206
|
account: {
|
|
231
207
|
name: 'account',
|
|
232
|
-
auth: 'required',
|
|
233
208
|
description: 'Admitted account view.',
|
|
234
209
|
target: {
|
|
235
210
|
kind: 'definition',
|
|
@@ -238,7 +213,6 @@ test('canonical Bundle views reject static schema and route-only identities', ()
|
|
|
238
213
|
},
|
|
239
214
|
sourceOnly: {
|
|
240
215
|
name: 'sourceOnly',
|
|
241
|
-
auth: 'optional',
|
|
242
216
|
description: 'Admitted source-only view.',
|
|
243
217
|
target: { kind: 'domain' },
|
|
244
218
|
},
|
|
@@ -247,18 +221,17 @@ test('canonical Bundle views reject static schema and route-only identities', ()
|
|
|
247
221
|
{
|
|
248
222
|
slug: 'account',
|
|
249
223
|
kind: 'spa',
|
|
250
|
-
auth: 'required',
|
|
251
224
|
description: 'Admitted account view.',
|
|
252
225
|
viewFor: 'Account',
|
|
253
226
|
url: 'https://shell.example.dev/account',
|
|
254
|
-
file: '
|
|
227
|
+
file: 'application.ts',
|
|
255
228
|
},
|
|
256
229
|
{
|
|
257
230
|
slug: 'sourceOnly',
|
|
258
|
-
kind: '
|
|
259
|
-
auth: 'optional',
|
|
231
|
+
kind: 'spa',
|
|
260
232
|
description: 'Admitted source-only view.',
|
|
261
|
-
|
|
233
|
+
url: 'https://shell.example.dev/source-only',
|
|
234
|
+
file: 'application.ts',
|
|
262
235
|
},
|
|
263
236
|
])
|
|
264
237
|
expect(buildViews(root, 'schema', {})).toEqual([])
|
|
@@ -6,28 +6,36 @@ import { join } from 'node:path'
|
|
|
6
6
|
import { buildAnatomy } from './anatomy'
|
|
7
7
|
|
|
8
8
|
const roots: string[] = []
|
|
9
|
-
|
|
10
9
|
afterEach(() => {
|
|
11
10
|
for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true })
|
|
12
11
|
})
|
|
13
12
|
|
|
14
|
-
function project(
|
|
15
|
-
const root = mkdtempSync(join(tmpdir(), 'studio-anatomy-
|
|
13
|
+
function project(nested: boolean) {
|
|
14
|
+
const root = mkdtempSync(join(tmpdir(), 'studio-anatomy-application-'))
|
|
16
15
|
roots.push(root)
|
|
17
|
-
|
|
16
|
+
const owner = nested ? join(root, 'domain') : root
|
|
17
|
+
mkdirSync(join(owner, 'schema'), { recursive: true })
|
|
18
18
|
writeFileSync(join(root, 'package.json'), '{}\n')
|
|
19
|
-
writeFileSync(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
writeFileSync(
|
|
20
|
+
join(root, 'astrale.config.ts'),
|
|
21
|
+
nested
|
|
22
|
+
? "import application from './domain/application.js'\nexport default { application }\n"
|
|
23
|
+
: 'export default {}\n',
|
|
24
|
+
)
|
|
25
|
+
writeFileSync(join(owner, 'application.ts'), 'export const application = {}\n')
|
|
26
|
+
writeFileSync(
|
|
27
|
+
join(owner, 'schema/index.ts'),
|
|
28
|
+
"defineSchema('example.astrale.ai', { classes: {} })\n",
|
|
29
|
+
)
|
|
30
|
+
return { root, schemaDirName: nested ? 'domain/schema' : 'schema' }
|
|
23
31
|
}
|
|
24
32
|
|
|
25
|
-
test('overview anchors
|
|
26
|
-
const
|
|
27
|
-
expect(
|
|
33
|
+
test('overview anchors a root Application', () => {
|
|
34
|
+
const input = project(false)
|
|
35
|
+
expect(buildAnatomy(input).overview.applicationFile).toBe('application.ts')
|
|
28
36
|
})
|
|
29
37
|
|
|
30
|
-
test('overview preserves
|
|
31
|
-
const
|
|
32
|
-
expect(
|
|
38
|
+
test('overview preserves the config-imported nested Application path', () => {
|
|
39
|
+
const input = project(true)
|
|
40
|
+
expect(buildAnatomy(input).overview.applicationFile).toBe('domain/application.ts')
|
|
33
41
|
})
|
|
@@ -12,6 +12,7 @@ import { join, relative } from 'node:path'
|
|
|
12
12
|
|
|
13
13
|
import type { DomainAnatomy, DomainOverview, SchemaIR } from '../../shared/types'
|
|
14
14
|
|
|
15
|
+
import { resolveApplicationEntry } from '../domain'
|
|
15
16
|
import { asJsonRecord, asString, parseJson } from '../json'
|
|
16
17
|
import { readSettings } from '../state/settings'
|
|
17
18
|
import { buildClientTree, buildEnvFields, buildViews, findSchemaDefinition } from './anatomy-extras'
|
|
@@ -59,15 +60,11 @@ function buildOverview(
|
|
|
59
60
|
|
|
60
61
|
const config = readConfigPreview(root)
|
|
61
62
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
: existsSync(join(root, 'domain.ts'))
|
|
65
|
-
? 'domain.ts'
|
|
66
|
-
: undefined
|
|
67
|
-
const domainSrc = compositionFile ? readTextSafe(join(root, compositionFile)) : ''
|
|
63
|
+
const application = resolveApplicationEntry(root)
|
|
64
|
+
const applicationSrc = application === null ? '' : readTextSafe(application)
|
|
68
65
|
const origin =
|
|
69
66
|
schemaOrigin ??
|
|
70
|
-
|
|
67
|
+
applicationSrc.match(/defineSchema\(\s*['"]([^'"]+)['"]/)?.[1] ??
|
|
71
68
|
readTextSafe(join(root, schemaDirName, 'index.ts')).match(
|
|
72
69
|
/defineSchema\(\s*['"]([^'"]+)['"]/,
|
|
73
70
|
)?.[1] ??
|
|
@@ -75,11 +72,11 @@ function buildOverview(
|
|
|
75
72
|
|
|
76
73
|
return {
|
|
77
74
|
origin,
|
|
78
|
-
|
|
75
|
+
applicationFile:
|
|
76
|
+
application === null ? undefined : relative(root, application).replaceAll('\\', '/'),
|
|
79
77
|
adapter: config.adapter,
|
|
80
78
|
prodTarget: config.prodTarget,
|
|
81
79
|
devSecrets: config.devSecrets,
|
|
82
|
-
postInstall: undefined,
|
|
83
80
|
requires: [],
|
|
84
81
|
packageName: pkg?.name,
|
|
85
82
|
packageVersion: pkg?.version,
|
|
@@ -18,7 +18,6 @@ export async function buildBundle(handle: DomainHandle): Promise<StudioSchemaBun
|
|
|
18
18
|
let schemaRoot: unknown | undefined
|
|
19
19
|
let schemaMode: StudioSchemaBundle['schemaMode'] = 'unavailable'
|
|
20
20
|
let schemaRevision: StudioSchemaBundle['schemaRevision']
|
|
21
|
-
let importedInterfaces: StudioSchemaBundle['importedInterfaces']
|
|
22
21
|
let error: StudioSchemaBundle['error'] = null
|
|
23
22
|
let extractedBy: StudioSchemaBundle['extractedBy'] = 'runtime-bun'
|
|
24
23
|
|
|
@@ -33,7 +32,6 @@ export async function buildBundle(handle: DomainHandle): Promise<StudioSchemaBun
|
|
|
33
32
|
if (r.root !== null) schemaRoot = r.root
|
|
34
33
|
schemaMode = r.schemaMode
|
|
35
34
|
if (r.revision !== null) schemaRevision = r.revision
|
|
36
|
-
importedInterfaces = r.importedInterfaces
|
|
37
35
|
} else {
|
|
38
36
|
error = { message: r.error?.message ?? 'schema failed to compile' }
|
|
39
37
|
extractedBy = 'static-tsmorph-fallback'
|
|
@@ -65,7 +63,6 @@ export async function buildBundle(handle: DomainHandle): Promise<StudioSchemaBun
|
|
|
65
63
|
ir,
|
|
66
64
|
...(schemaRoot === undefined ? {} : { schemaRoot }),
|
|
67
65
|
overlay,
|
|
68
|
-
importedInterfaces,
|
|
69
66
|
error,
|
|
70
67
|
extractedAt: new Date().toISOString(),
|
|
71
68
|
}
|