@astrale-os/cli 1.0.0-beta.2 → 1.0.0-beta.20
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 +16 -1
- package/dist/astrale.js +51105 -58057
- package/dist/public/connect-core.js +2085 -30702
- package/dist/public/keys/index.js +884 -29476
- package/dist/public/paths/index.js +13101 -41452
- 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 +7 -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/package.json +15 -20
- 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 +46 -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 +7 -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 +3 -14
- 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 +62 -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 +49 -0
- package/src/commands/call-describe.ts +60 -68
- package/src/commands/call.ts +71 -59
- package/src/commands/domain/install.ts +54 -35
- 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 +14 -15
- package/src/commands/identity/__tests__/register.test.ts +3 -3
- package/src/commands/identity/register.ts +5 -4
- 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 +48 -35
- package/src/commands/logs.ts +123 -33
- package/src/commands/mutate.ts +6 -5
- package/src/commands/query.ts +35 -32
- 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 +13 -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 +31 -11
- package/src/commands/view.ts +82 -37
- package/src/connection/.spec/api.d.ts +7 -8
- package/src/connection/.spec/architecture.md +5 -4
- 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__/credential.test.ts +20 -1
- package/src/connection/__tests__/errors.test.ts +27 -20
- package/src/connection/__tests__/exchange.test.ts +30 -1
- 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 +3 -3
- package/src/connection/__tests__/target.test.ts +1 -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 +47 -23
- 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 +19 -8
- 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__/registration.test.ts +1 -1
- package/src/identity/registration.ts +3 -3
- 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__/command-dx.test.ts +1 -1
- 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__/studio-server-deps.test.ts +1 -1
- package/src/lib/__tests__/update.test.ts +264 -11
- package/src/lib/__tests__/view-assets.test.ts +14 -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/command-dx.ts +9 -9
- 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/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/telemetry/__tests__/recorder.test.ts +1 -0
- package/src/telemetry/recorder.ts +9 -1
- package/src/ui/.spec/api.d.ts +14 -0
- package/src/ui/.spec/architecture.md +10 -0
- package/src/ui/.spec/laws.ts +36 -0
- package/src/ui/.spec/layout.ts +16 -0
- package/src/ui/__tests__/ui.test.ts +981 -0
- package/src/ui/index.ts +13 -0
- package/src/ui/lock.ts +87 -0
- package/src/ui/model.ts +83 -0
- package/src/ui/operations.ts +710 -0
- package/src/ui/project.ts +219 -0
- package/src/ui/release.ts +321 -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-7YHdeCxp.js +81 -0
- package/studio/client/dist/assets/index-C0FAnwNw.css +2 -0
- package/studio/client/dist/assets/rolldown-runtime-Dd_uD5pT.js +1 -0
- package/studio/client/dist/assets/schema-studio-BilUNb6Z.css +1 -0
- package/studio/client/dist/assets/schema-studio-CABpTfvH.js +8 -0
- package/studio/client/dist/index.html +3 -2
- package/studio/package.json +7 -13
- 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 +32 -36
- package/studio/server/agent/prompts/anchors.ts +20 -49
- package/studio/server/agent/prompts/system.test.ts +3 -2
- package/studio/server/agent/prompts/system.ts +3 -3
- package/studio/server/agent/routes.test.ts +1 -1
- package/studio/server/agent/run/coordinator.test.ts +1 -1
- package/studio/server/api/canvas.ts +0 -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 +23 -12
- package/studio/server/cache.ts +12 -15
- package/studio/server/domain.test.ts +50 -68
- package/studio/server/domain.ts +82 -63
- package/studio/server/handoff/copy.ts +1 -1
- 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 +9 -14
- package/studio/server/introspect/anatomy-extras.test.ts +26 -42
- 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 +94 -389
- package/studio/server/introspect/canonical-schema.ts +227 -457
- package/studio/server/introspect/core-extractor.ts +18 -127
- package/studio/server/introspect/core.ts +1 -2
- package/studio/server/introspect/diff.test.ts +11 -7
- package/studio/server/introspect/diff.ts +18 -55
- package/studio/server/introspect/extractor.ts +22 -117
- package/studio/server/introspect/overlay-tsmorph.test.ts +119 -240
- package/studio/server/introspect/overlay.test.ts +26 -54
- package/studio/server/introspect/overlay.ts +10 -37
- package/studio/server/introspect/revision.test.ts +1 -1
- package/studio/server/introspect/revision.ts +1 -1
- package/studio/server/introspect/runtime.test.ts +65 -183
- package/studio/server/introspect/runtime.ts +8 -25
- package/studio/server/introspect/schema-ir-json.test.ts +70 -0
- package/studio/server/introspect/schema-ir-json.ts +38 -68
- 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/state/baseline.test.ts +14 -9
- package/studio/server/state/baseline.ts +3 -5
- package/studio/server/state/visibility.ts +1 -5
- package/studio/server/views/model.ts +3 -3
- package/studio/server/views/target.test.ts +17 -74
- 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-watch.ts +2 -2
- package/studio/shared/contracts/schema.ts +38 -107
- package/studio/shared/contracts/surface.test.ts +13 -15
- package/studio/shared/contracts/workspace.ts +2 -11
- package/studio/shared/schema/identity.test.ts +20 -44
- package/studio/shared/schema/identity.ts +9 -23
- package/viewer/dist/main.js +30 -51
- 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
|
@@ -11,7 +11,6 @@ import { admittedBundleRevision } from './revision'
|
|
|
11
11
|
import { coreExtract, runtimeExtract } from './runtime'
|
|
12
12
|
|
|
13
13
|
const roots: string[] = []
|
|
14
|
-
|
|
15
14
|
afterEach(() => {
|
|
16
15
|
while (roots.length > 0) rmSync(roots.pop()!, { recursive: true, force: true })
|
|
17
16
|
})
|
|
@@ -22,170 +21,114 @@ function fixtureRoot(label: string): string {
|
|
|
22
21
|
mkdirSync(join(root, 'schema'), { recursive: true })
|
|
23
22
|
writeFileSync(join(root, 'package.json'), '{"type":"module"}\n')
|
|
24
23
|
writeFileSync(join(root, 'astrale.config.ts'), 'export default {}\n')
|
|
25
|
-
return root
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function linkCurrentSdk(root: string): void {
|
|
29
24
|
const sdk = realpathSync(join(import.meta.dir, '../../../node_modules/@astrale-os/sdk'))
|
|
30
25
|
const scope = join(root, 'node_modules', '@astrale-os')
|
|
31
26
|
mkdirSync(scope, { recursive: true })
|
|
32
27
|
symlinkSync(sdk, join(scope, 'sdk'), 'dir')
|
|
28
|
+
return root
|
|
33
29
|
}
|
|
34
30
|
|
|
35
31
|
function currentFixture(): DomainHandle {
|
|
36
32
|
const root = fixtureRoot('canonical-runtime')
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
const domainFile = join(root, 'implementation.ts')
|
|
33
|
+
const schemaIndex = join(root, 'schema/index.ts')
|
|
34
|
+
const applicationFile = join(root, 'application.ts')
|
|
40
35
|
writeFileSync(
|
|
41
36
|
schemaIndex,
|
|
42
37
|
`
|
|
43
|
-
import {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
output: { type: 'boolean' },
|
|
59
|
-
auth: 'authenticated',
|
|
60
|
-
})
|
|
61
|
-
const Document = nodeClass({
|
|
62
|
-
implements: [Named],
|
|
63
|
-
properties: { title: property({ type: 'string' }, { required: true }) },
|
|
64
|
-
methods: { rename },
|
|
65
|
-
})
|
|
66
|
-
const owned_by = edgeClass.directed({
|
|
67
|
-
source: { as: 'document', accepts: [Document], outgoing: '0..*' },
|
|
68
|
-
target: { as: 'owner', accepts: [Document], incoming: '0..*' },
|
|
69
|
-
})
|
|
70
|
-
const welcome = node(Document, { title: 'Welcome' })
|
|
71
|
-
|
|
72
|
-
export const schema = defineSchema('documents.runtime.test', {
|
|
73
|
-
dependencies: [Directory],
|
|
74
|
-
classes: { Document, owned_by },
|
|
75
|
-
functions: {
|
|
76
|
-
exportAll: fn({
|
|
77
|
-
input: { type: 'object', properties: {}, required: [], additionalProperties: false },
|
|
78
|
-
output: output.binary(),
|
|
79
|
-
auth: 'authenticated',
|
|
80
|
-
}),
|
|
81
|
-
},
|
|
82
|
-
views: { editor: view({ target: Document, auth: 'optional' }) },
|
|
83
|
-
core: {
|
|
84
|
-
nodes: { welcome },
|
|
85
|
-
edges: [edge(welcome, owned_by, domain(), {})],
|
|
86
|
-
},
|
|
87
|
-
})
|
|
88
|
-
export const installedBundle = bundle.create(schema)
|
|
89
|
-
`,
|
|
38
|
+
import { bundle, core, defineSchema, nodeClass, view } from '@astrale-os/sdk/schema'
|
|
39
|
+
const Named = nodeClass({ properties: {} })
|
|
40
|
+
export const DirectorySchema = defineSchema('directory.runtime.test', {
|
|
41
|
+
classes: { Named },
|
|
42
|
+
})
|
|
43
|
+
const Document = nodeClass({ extends: [Named], properties: {} })
|
|
44
|
+
const welcome = core.node(Document, {})
|
|
45
|
+
export const schema = defineSchema('documents.runtime.test', {
|
|
46
|
+
dependencies: { directory: DirectorySchema },
|
|
47
|
+
classes: { Document },
|
|
48
|
+
views: { editor: view({ target: Document }) },
|
|
49
|
+
core: { nodes: { welcome } },
|
|
50
|
+
})
|
|
51
|
+
export const installedBundle = bundle.create(schema)
|
|
52
|
+
`,
|
|
90
53
|
)
|
|
91
|
-
|
|
92
|
-
writeFileSync(domainFile, `throw new Error('composition entry was imported')\n`)
|
|
54
|
+
writeFileSync(applicationFile, `throw new Error('Application entry was imported')\n`)
|
|
93
55
|
return {
|
|
94
56
|
id: 'documents-runtime-test',
|
|
95
57
|
root,
|
|
96
58
|
configFile: join(root, 'astrale.config.ts'),
|
|
97
|
-
|
|
59
|
+
applicationFile,
|
|
98
60
|
schemaDirName: 'schema',
|
|
99
61
|
schemaDir: join(root, 'schema'),
|
|
100
62
|
schemaIndex,
|
|
101
63
|
}
|
|
102
64
|
}
|
|
103
65
|
|
|
104
|
-
describe('
|
|
105
|
-
test('
|
|
66
|
+
describe('SDK V1 schema extractor', () => {
|
|
67
|
+
test('uses the authored SDK for admission and projects exact imported Classes', async () => {
|
|
106
68
|
const handle = currentFixture()
|
|
107
69
|
const result = await runtimeExtract(handle.schemaIndex, handle.root)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
origin: 'documents.runtime.test',
|
|
116
|
-
})
|
|
117
|
-
expect(result.ir).toMatchObject({
|
|
118
|
-
format: 'astrale.dsl',
|
|
119
|
-
domain: 'documents.runtime.test',
|
|
120
|
-
functions: {
|
|
121
|
-
exportAll: {
|
|
122
|
-
static: true,
|
|
123
|
-
inheritance: 'default',
|
|
124
|
-
output: { mode: 'binary' },
|
|
125
|
-
},
|
|
70
|
+
expect(result).toMatchObject({
|
|
71
|
+
ok: true,
|
|
72
|
+
schemaMode: 'canonical-admitted',
|
|
73
|
+
root: {
|
|
74
|
+
format: 'astrale.dsl',
|
|
75
|
+
version: 'v1',
|
|
76
|
+
origin: 'documents.runtime.test',
|
|
126
77
|
},
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
78
|
+
ir: {
|
|
79
|
+
domain: 'documents.runtime.test',
|
|
80
|
+
views: { editor: { auth: 'required', target: { kind: 'definition' } } },
|
|
81
|
+
importsByKey: {
|
|
82
|
+
'directory.runtime.test:class.Named': {
|
|
83
|
+
ref: { origin: 'directory.runtime.test', kind: 'class', name: 'Named' },
|
|
84
|
+
},
|
|
131
85
|
},
|
|
132
86
|
},
|
|
133
87
|
})
|
|
134
|
-
expect(result.
|
|
135
|
-
name: 'Named',
|
|
136
|
-
origin: 'directory.runtime.test',
|
|
137
|
-
})
|
|
88
|
+
expect(result.revision).toMatch(/^sha256:[0-9a-f]{64}$/)
|
|
138
89
|
})
|
|
139
90
|
|
|
140
|
-
test('transports the DSL revision
|
|
91
|
+
test('transports the DSL revision while keeping render identity separate', async () => {
|
|
141
92
|
const handle = currentFixture()
|
|
142
93
|
const extracted = await runtimeExtract(handle.schemaIndex, handle.root)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
expect(
|
|
148
|
-
expect(
|
|
149
|
-
expect(bundle.schemaRevision).toBe(extracted.revision)
|
|
150
|
-
expect(bundle.renderFingerprint).toBe(renderFingerprintOf(extracted.root))
|
|
151
|
-
expect(bundle.renderFingerprint).not.toBe(renderFingerprintOf(extracted.ir))
|
|
94
|
+
if (extracted.revision === null) throw new Error('expected an admitted Schema revision')
|
|
95
|
+
const built = await buildBundle(handle)
|
|
96
|
+
expect(built.schemaRoot).toEqual(extracted.root)
|
|
97
|
+
expect(built.schemaRevision).toBe(extracted.revision)
|
|
98
|
+
expect(built.renderFingerprint).toBe(renderFingerprintOf(extracted.root))
|
|
99
|
+
expect(built.renderFingerprint).not.toBe(renderFingerprintOf(extracted.ir))
|
|
152
100
|
})
|
|
153
101
|
|
|
154
|
-
test('re-admits installed Bundle JSON before comparing its
|
|
102
|
+
test('re-admits installed Bundle JSON before comparing its revision', async () => {
|
|
155
103
|
const handle = currentFixture()
|
|
156
104
|
const extracted = await runtimeExtract(handle.schemaIndex, handle.root)
|
|
157
|
-
if (extracted.revision === null) throw new Error('expected an admitted
|
|
105
|
+
if (extracted.revision === null) throw new Error('expected an admitted Schema revision')
|
|
158
106
|
const fixture = (await import(handle.schemaIndex)) as { installedBundle: unknown }
|
|
159
107
|
const installedWire = JSON.parse(JSON.stringify(fixture.installedBundle))
|
|
160
|
-
|
|
161
108
|
expect(await admittedBundleRevision(handle.root, installedWire)).toBe(extracted.revision)
|
|
162
109
|
})
|
|
163
110
|
|
|
164
|
-
test('renders a V1-shaped
|
|
111
|
+
test('renders a V1-shaped root as preview when SDK admission fails', async () => {
|
|
165
112
|
const root = fixtureRoot('canonical-preview')
|
|
166
|
-
|
|
167
|
-
const schemaIndex = join(root, 'schema', 'index.ts')
|
|
113
|
+
const schemaIndex = join(root, 'schema/index.ts')
|
|
168
114
|
writeFileSync(
|
|
169
115
|
schemaIndex,
|
|
170
116
|
`export const schema = {
|
|
171
117
|
format: 'astrale.dsl', version: 'v1', origin: 'not an origin',
|
|
172
|
-
dependencies:
|
|
173
|
-
|
|
118
|
+
dependencies: {}, classes: {}, functions: {}, policies: {}, views: {},
|
|
119
|
+
core: { nodes: {}, edges: [] },
|
|
174
120
|
}\n`,
|
|
175
121
|
)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
expect(result.root).toMatchObject({ format: 'astrale.dsl', version: 'v1' })
|
|
122
|
+
expect(await runtimeExtract(schemaIndex, root)).toMatchObject({
|
|
123
|
+
ok: true,
|
|
124
|
+
schemaMode: 'canonical-preview',
|
|
125
|
+
revision: null,
|
|
126
|
+
})
|
|
182
127
|
})
|
|
183
128
|
|
|
184
|
-
test('extracts
|
|
129
|
+
test('extracts Core through the pure Schema entry without importing Application', async () => {
|
|
185
130
|
const handle = currentFixture()
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
expect(result).toEqual({
|
|
131
|
+
expect(await coreExtract(handle.schemaIndex, handle.root)).toEqual({
|
|
189
132
|
ok: true,
|
|
190
133
|
core: {
|
|
191
134
|
domain: 'documents.runtime.test',
|
|
@@ -193,83 +136,22 @@ describe('current SDK schema extractor', () => {
|
|
|
193
136
|
{
|
|
194
137
|
path: '/:documents.runtime.test:core.welcome',
|
|
195
138
|
className: 'Document',
|
|
196
|
-
data: { 'documents.runtime.test:class.Document.property.title': 'Welcome' },
|
|
197
|
-
},
|
|
198
|
-
],
|
|
199
|
-
edges: [
|
|
200
|
-
{
|
|
201
|
-
from: '/:documents.runtime.test:core.welcome',
|
|
202
|
-
to: '/:documents.runtime.test',
|
|
203
|
-
edgeName: 'owned_by',
|
|
204
139
|
data: {},
|
|
205
140
|
},
|
|
206
141
|
],
|
|
142
|
+
edges: [],
|
|
207
143
|
},
|
|
208
144
|
})
|
|
209
145
|
})
|
|
210
146
|
})
|
|
211
147
|
|
|
212
|
-
test('
|
|
213
|
-
const root = fixtureRoot('
|
|
214
|
-
const schemaIndex = join(root, 'schema
|
|
215
|
-
writeFileSync(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
classes: {}, imports: {}, functions: {},
|
|
220
|
-
} } }\n`,
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
const result = await runtimeExtract(schemaIndex, root)
|
|
224
|
-
expect(result).toMatchObject({
|
|
225
|
-
ok: true,
|
|
226
|
-
schemaMode: 'legacy',
|
|
148
|
+
test('rejects the removed compiled-IR compatibility envelope', async () => {
|
|
149
|
+
const root = fixtureRoot('removed-runtime')
|
|
150
|
+
const schemaIndex = join(root, 'schema/index.ts')
|
|
151
|
+
writeFileSync(schemaIndex, `export const D = { $: { ir: { domain: 'legacy' } } }\n`)
|
|
152
|
+
expect(await runtimeExtract(schemaIndex, root)).toMatchObject({
|
|
153
|
+
ok: false,
|
|
154
|
+
schemaMode: 'unavailable',
|
|
227
155
|
revision: null,
|
|
228
|
-
root: null,
|
|
229
|
-
ir: { domain: 'legacy.runtime.test', functions: {} },
|
|
230
|
-
})
|
|
231
|
-
})
|
|
232
|
-
|
|
233
|
-
test('core extractor preserves the legacy defineCore fallback', async () => {
|
|
234
|
-
const root = fixtureRoot('legacy-core')
|
|
235
|
-
const schemaIndex = join(root, 'schema', 'index.ts')
|
|
236
|
-
const domainFile = join(root, 'domain.ts')
|
|
237
|
-
writeFileSync(schemaIndex, `export const schema = { domain: 'legacy.runtime.test' }\n`)
|
|
238
|
-
writeFileSync(
|
|
239
|
-
domainFile,
|
|
240
|
-
`
|
|
241
|
-
const Item = { config: { name: 'Item' } }
|
|
242
|
-
const linked = { config: { name: 'linked' } }
|
|
243
|
-
const schema = { interfaces: {}, classes: { Item, linked }, imports: [] }
|
|
244
|
-
export const core = {
|
|
245
|
-
domain: 'legacy.runtime.test', schema,
|
|
246
|
-
__nodes: [
|
|
247
|
-
{ path: '/legacy/left', def: Item, data: { name: 'Left' } },
|
|
248
|
-
{ path: '/legacy/right', def: Item, data: { name: 'Right' } },
|
|
249
|
-
],
|
|
250
|
-
__edges: [
|
|
251
|
-
{ from: '/legacy/left', to: '/legacy/right', edge: linked, data: { order: 1 } },
|
|
252
|
-
],
|
|
253
|
-
}
|
|
254
|
-
`,
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
expect(await coreExtract(schemaIndex, domainFile, root)).toEqual({
|
|
258
|
-
ok: true,
|
|
259
|
-
core: {
|
|
260
|
-
domain: 'legacy.runtime.test',
|
|
261
|
-
nodes: [
|
|
262
|
-
{ path: '/legacy/left', className: 'Item', data: { name: 'Left' } },
|
|
263
|
-
{ path: '/legacy/right', className: 'Item', data: { name: 'Right' } },
|
|
264
|
-
],
|
|
265
|
-
edges: [
|
|
266
|
-
{
|
|
267
|
-
from: '/legacy/left',
|
|
268
|
-
to: '/legacy/right',
|
|
269
|
-
edgeName: 'linked',
|
|
270
|
-
data: { order: 1 },
|
|
271
|
-
},
|
|
272
|
-
],
|
|
273
|
-
},
|
|
274
156
|
})
|
|
275
157
|
})
|
|
@@ -5,13 +5,7 @@
|
|
|
5
5
|
* render IR plus the raw canonical root (when present), or an error render-state
|
|
6
6
|
* — never throws.
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
9
|
-
IrInterface,
|
|
10
|
-
SchemaIR,
|
|
11
|
-
SchemaRevision,
|
|
12
|
-
StudioCore,
|
|
13
|
-
StudioSchemaBundle,
|
|
14
|
-
} from '../../shared/types'
|
|
8
|
+
import type { SchemaIR, SchemaRevision, StudioCore, StudioSchemaBundle } from '../../shared/types'
|
|
15
9
|
|
|
16
10
|
import { isSchemaRevision } from '../../shared/types'
|
|
17
11
|
|
|
@@ -21,13 +15,11 @@ const CORE_EXTRACTOR = new URL('./core-extractor.ts', import.meta.url).pathname
|
|
|
21
15
|
export interface RuntimeExtractResult {
|
|
22
16
|
ok: boolean
|
|
23
17
|
ir: SchemaIR | null
|
|
24
|
-
/** Portable canonical V1 document. Null for
|
|
18
|
+
/** Portable canonical V1 document. Null only for failures. */
|
|
25
19
|
root: unknown | null
|
|
26
20
|
schemaMode: StudioSchemaBundle['schemaMode']
|
|
27
|
-
/** Present only when the Domain
|
|
21
|
+
/** Present only when the Domain's installed SDK admitted `root`. */
|
|
28
22
|
revision: SchemaRevision | null
|
|
29
|
-
/** member bodies of imported (kernel + cross-domain) interfaces, by name */
|
|
30
|
-
importedInterfaces?: Record<string, IrInterface>
|
|
31
23
|
error?: { message: string }
|
|
32
24
|
}
|
|
33
25
|
|
|
@@ -70,16 +62,10 @@ export async function runtimeExtract(
|
|
|
70
62
|
}
|
|
71
63
|
const schemaMode = parsed.schemaMode
|
|
72
64
|
const revision = parsed.revision
|
|
73
|
-
const validMode =
|
|
74
|
-
schemaMode === 'canonical-admitted' ||
|
|
75
|
-
schemaMode === 'canonical-preview' ||
|
|
76
|
-
schemaMode === 'legacy'
|
|
65
|
+
const validMode = schemaMode === 'canonical-admitted' || schemaMode === 'canonical-preview'
|
|
77
66
|
const validRevision =
|
|
78
67
|
schemaMode === 'canonical-admitted' ? isSchemaRevision(revision) : revision == null
|
|
79
|
-
const validRoot =
|
|
80
|
-
schemaMode === 'legacy'
|
|
81
|
-
? parsed.root == null
|
|
82
|
-
: parsed.root !== null && parsed.root !== undefined
|
|
68
|
+
const validRoot = parsed.root !== null && parsed.root !== undefined
|
|
83
69
|
if (!validMode || !validRevision || !validRoot) {
|
|
84
70
|
return {
|
|
85
71
|
ok: false,
|
|
@@ -96,7 +82,6 @@ export async function runtimeExtract(
|
|
|
96
82
|
root: parsed.root ?? null,
|
|
97
83
|
schemaMode,
|
|
98
84
|
revision: revision ?? null,
|
|
99
|
-
importedInterfaces: (parsed.importedInterfaces ?? {}) as Record<string, IrInterface>,
|
|
100
85
|
}
|
|
101
86
|
} catch (e: any) {
|
|
102
87
|
return {
|
|
@@ -118,18 +103,16 @@ export interface CoreExtractResult {
|
|
|
118
103
|
}
|
|
119
104
|
|
|
120
105
|
/**
|
|
121
|
-
* Spawn the
|
|
122
|
-
*
|
|
123
|
-
* resolved core graph or an error — never throws.
|
|
106
|
+
* Spawn the Core extractor over the pure Schema entry. Returns the projected
|
|
107
|
+
* graph or an error and never imports Application or Runtime modules.
|
|
124
108
|
*/
|
|
125
109
|
export async function coreExtract(
|
|
126
110
|
schemaIndexPath: string,
|
|
127
|
-
domainFile: string,
|
|
128
111
|
domainDir: string,
|
|
129
112
|
timeoutMs = 20000,
|
|
130
113
|
): Promise<CoreExtractResult> {
|
|
131
114
|
try {
|
|
132
|
-
const proc = Bun.spawn(['bun', 'run', CORE_EXTRACTOR, schemaIndexPath,
|
|
115
|
+
const proc = Bun.spawn(['bun', 'run', CORE_EXTRACTOR, schemaIndexPath, domainDir], {
|
|
133
116
|
cwd: domainDir,
|
|
134
117
|
stdout: 'pipe',
|
|
135
118
|
stderr: 'pipe',
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { expect, test } from 'bun:test'
|
|
2
|
+
|
|
3
|
+
import { decodeSchemaIR } from './schema-ir-json'
|
|
4
|
+
|
|
5
|
+
function canonicalIr() {
|
|
6
|
+
return {
|
|
7
|
+
format: 'astrale.dsl',
|
|
8
|
+
version: 'v1',
|
|
9
|
+
domain: 'example.test',
|
|
10
|
+
classes: {
|
|
11
|
+
Document: {
|
|
12
|
+
type: 'node',
|
|
13
|
+
name: 'Document',
|
|
14
|
+
origin: 'example.test',
|
|
15
|
+
ref: { origin: 'example.test', kind: 'class', name: 'Document' },
|
|
16
|
+
properties: {},
|
|
17
|
+
methods: {
|
|
18
|
+
rename: {
|
|
19
|
+
name: 'rename',
|
|
20
|
+
input: { type: 'object', properties: {} },
|
|
21
|
+
output: { mode: 'value', schema: { type: 'boolean' } },
|
|
22
|
+
static: false,
|
|
23
|
+
inheritance: 'default',
|
|
24
|
+
auth: 'authorized',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
importsByKey: {},
|
|
30
|
+
importedClassesByKey: {},
|
|
31
|
+
functions: {
|
|
32
|
+
search: {
|
|
33
|
+
name: 'search',
|
|
34
|
+
input: { type: 'object', properties: {} },
|
|
35
|
+
output: { mode: 'stream', item: { type: 'string' } },
|
|
36
|
+
auth: 'authenticated',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
views: {},
|
|
40
|
+
policies: {},
|
|
41
|
+
dependencies: [],
|
|
42
|
+
core: {},
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
test('admits the complete canonical Studio projection', () => {
|
|
47
|
+
expect(decodeSchemaIR(canonicalIr())).toMatchObject({
|
|
48
|
+
format: 'astrale.dsl',
|
|
49
|
+
domain: 'example.test',
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('rejects stale projections that lost canonical callable contracts', () => {
|
|
54
|
+
const input = canonicalIr()
|
|
55
|
+
const rename = input.classes.Document.methods.rename as Record<string, unknown>
|
|
56
|
+
delete rename.input
|
|
57
|
+
delete rename.output
|
|
58
|
+
Object.assign(rename, { params: {}, returns: { type: 'boolean' } })
|
|
59
|
+
expect(decodeSchemaIR(input)).toBeUndefined()
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('rejects unversioned and incomplete projection roots', () => {
|
|
63
|
+
const withoutFormat = canonicalIr() as Record<string, unknown>
|
|
64
|
+
delete withoutFormat.format
|
|
65
|
+
expect(decodeSchemaIR(withoutFormat)).toBeUndefined()
|
|
66
|
+
|
|
67
|
+
const withoutViews = canonicalIr() as Record<string, unknown>
|
|
68
|
+
delete withoutViews.views
|
|
69
|
+
expect(decodeSchemaIR(withoutViews)).toBeUndefined()
|
|
70
|
+
})
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/** Structural admission for persisted Studio render IR. SDK admission is separate. */
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
|
+
IrClass,
|
|
5
|
+
IrClassRef,
|
|
4
6
|
IrFunction,
|
|
5
|
-
IrInterface,
|
|
6
7
|
IrMethod,
|
|
7
8
|
IrSchemaRef,
|
|
8
9
|
JsonSchema,
|
|
@@ -11,10 +12,6 @@ import type {
|
|
|
11
12
|
|
|
12
13
|
import { asJsonRecord, asStringArray } from '../json'
|
|
13
14
|
|
|
14
|
-
function optional<T>(value: unknown, guard: (candidate: unknown) => candidate is T): boolean {
|
|
15
|
-
return value === undefined || guard(value)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
15
|
function recordOf(value: unknown, guard: (candidate: unknown) => boolean): boolean {
|
|
19
16
|
const record = asJsonRecord(value)
|
|
20
17
|
return !!record && Object.values(record).every(guard)
|
|
@@ -29,14 +26,12 @@ function isSchemaRef(value: unknown): value is IrSchemaRef {
|
|
|
29
26
|
return (
|
|
30
27
|
typeof record?.origin === 'string' &&
|
|
31
28
|
typeof record.name === 'string' &&
|
|
32
|
-
['
|
|
33
|
-
String(record.kind),
|
|
34
|
-
)
|
|
29
|
+
['class', 'function', 'policy', 'view', 'core'].includes(String(record.kind))
|
|
35
30
|
)
|
|
36
31
|
}
|
|
37
32
|
|
|
38
|
-
function
|
|
39
|
-
return
|
|
33
|
+
function isClassRef(value: unknown): value is IrClassRef {
|
|
34
|
+
return isSchemaRef(value) && value.kind === 'class'
|
|
40
35
|
}
|
|
41
36
|
|
|
42
37
|
function isOutput(value: unknown): boolean {
|
|
@@ -52,20 +47,22 @@ function isMethod(value: unknown): value is IrMethod {
|
|
|
52
47
|
const record = asJsonRecord(value)
|
|
53
48
|
return (
|
|
54
49
|
typeof record?.name === 'string' &&
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
isJsonSchema(record.input) &&
|
|
51
|
+
isOutput(record.output) &&
|
|
57
52
|
typeof record.static === 'boolean' &&
|
|
58
|
-
['default', 'abstract', 'sealed'].includes(String(record.inheritance))
|
|
59
|
-
optional(record.input, isJsonSchema) &&
|
|
60
|
-
(record.requiredParams === undefined || asStringArray(record.requiredParams) !== undefined) &&
|
|
61
|
-
(record.output === undefined || isOutput(record.output))
|
|
53
|
+
['default', 'abstract', 'sealed'].includes(String(record.inheritance))
|
|
62
54
|
)
|
|
63
55
|
}
|
|
64
56
|
|
|
65
57
|
function isEndpoint(value: unknown): boolean {
|
|
66
58
|
const record = asJsonRecord(value)
|
|
67
59
|
if (!record || typeof record.name !== 'string' || !asStringArray(record.types)) return false
|
|
68
|
-
if (
|
|
60
|
+
if (
|
|
61
|
+
record.refs !== undefined &&
|
|
62
|
+
(!Array.isArray(record.refs) || !record.refs.every(isSchemaRef))
|
|
63
|
+
) {
|
|
64
|
+
return false
|
|
65
|
+
}
|
|
69
66
|
if (record.cardinality !== undefined) {
|
|
70
67
|
const cardinality = asJsonRecord(record.cardinality)
|
|
71
68
|
if (
|
|
@@ -81,31 +78,19 @@ function isEndpoint(value: unknown): boolean {
|
|
|
81
78
|
return true
|
|
82
79
|
}
|
|
83
80
|
|
|
84
|
-
function
|
|
85
|
-
const record = asJsonRecord(value)
|
|
86
|
-
return (
|
|
87
|
-
record?.type === 'interface' &&
|
|
88
|
-
typeof record.name === 'string' &&
|
|
89
|
-
recordOf(record.properties, isJsonSchema) &&
|
|
90
|
-
recordOf(record.methods, isMethod) &&
|
|
91
|
-
(record.required === undefined || asStringArray(record.required) !== undefined) &&
|
|
92
|
-
(record.extends === undefined || asStringArray(record.extends) !== undefined) &&
|
|
93
|
-
(record.extendsRefs === undefined || isSchemaRefArray(record.extendsRefs)) &&
|
|
94
|
-
(record.endpoints === undefined ||
|
|
95
|
-
(Array.isArray(record.endpoints) && record.endpoints.every(isEndpoint)))
|
|
96
|
-
)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function isClass(value: unknown): boolean {
|
|
81
|
+
function isClass(value: unknown): value is IrClass {
|
|
100
82
|
const record = asJsonRecord(value)
|
|
101
83
|
return (
|
|
102
84
|
(record?.type === 'node' || record?.type === 'edge') &&
|
|
103
85
|
typeof record.name === 'string' &&
|
|
86
|
+
typeof record.origin === 'string' &&
|
|
87
|
+
isClassRef(record.ref) &&
|
|
104
88
|
recordOf(record.properties, isJsonSchema) &&
|
|
105
89
|
recordOf(record.methods, isMethod) &&
|
|
106
90
|
(record.required === undefined || asStringArray(record.required) !== undefined) &&
|
|
107
|
-
(record.
|
|
108
|
-
(record.
|
|
91
|
+
(record.extends === undefined || asStringArray(record.extends) !== undefined) &&
|
|
92
|
+
(record.extendsRefs === undefined ||
|
|
93
|
+
(Array.isArray(record.extendsRefs) && record.extendsRefs.every(isClassRef))) &&
|
|
109
94
|
(record.endpoints === undefined ||
|
|
110
95
|
(Array.isArray(record.endpoints) && record.endpoints.every(isEndpoint)))
|
|
111
96
|
)
|
|
@@ -113,24 +98,16 @@ function isClass(value: unknown): boolean {
|
|
|
113
98
|
|
|
114
99
|
function isFunction(value: unknown): value is IrFunction {
|
|
115
100
|
const record = asJsonRecord(value)
|
|
116
|
-
return (
|
|
117
|
-
typeof record?.name === 'string' &&
|
|
118
|
-
isJsonSchema(record.input) &&
|
|
119
|
-
recordOf(record.params, isJsonSchema) &&
|
|
120
|
-
(record.requiredParams === undefined || asStringArray(record.requiredParams) !== undefined) &&
|
|
121
|
-
isOutput(record.output) &&
|
|
122
|
-
isJsonSchema(record.returns) &&
|
|
123
|
-
record.static === true &&
|
|
124
|
-
record.inheritance === 'default'
|
|
125
|
-
)
|
|
101
|
+
return typeof record?.name === 'string' && isJsonSchema(record.input) && isOutput(record.output)
|
|
126
102
|
}
|
|
127
103
|
|
|
128
104
|
function isImport(value: unknown): boolean {
|
|
129
105
|
const record = asJsonRecord(value)
|
|
130
106
|
return (
|
|
131
107
|
typeof record?.origin === 'string' &&
|
|
132
|
-
(record.
|
|
133
|
-
|
|
108
|
+
isClassRef(record.ref) &&
|
|
109
|
+
typeof record.key === 'string' &&
|
|
110
|
+
record.key === `${record.ref.origin}:class.${record.ref.name}`
|
|
134
111
|
)
|
|
135
112
|
}
|
|
136
113
|
|
|
@@ -142,7 +119,9 @@ function isView(value: unknown): boolean {
|
|
|
142
119
|
['required', 'optional', 'public'].includes(String(record.auth)) &&
|
|
143
120
|
!!target &&
|
|
144
121
|
(target.kind === 'domain' ||
|
|
145
|
-
(target.kind === 'definition' &&
|
|
122
|
+
(target.kind === 'definition' &&
|
|
123
|
+
Array.isArray(target.definitions) &&
|
|
124
|
+
target.definitions.every(isSchemaRef)))
|
|
146
125
|
)
|
|
147
126
|
}
|
|
148
127
|
|
|
@@ -150,32 +129,23 @@ export function decodeSchemaIR(value: unknown): SchemaIR | undefined {
|
|
|
150
129
|
const record = asJsonRecord(value)
|
|
151
130
|
if (
|
|
152
131
|
!record ||
|
|
132
|
+
record.format !== 'astrale.dsl' ||
|
|
153
133
|
typeof record.version !== 'string' ||
|
|
154
134
|
typeof record.domain !== 'string' ||
|
|
155
|
-
!recordOf(record.types, isJsonSchema) ||
|
|
156
|
-
!recordOf(record.interfaces, isInterface) ||
|
|
157
135
|
!recordOf(record.classes, isClass) ||
|
|
158
|
-
!recordOf(record.imports, isImport) ||
|
|
159
136
|
!recordOf(record.functions, isFunction) ||
|
|
160
|
-
|
|
161
|
-
(record.
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
})))
|
|
137
|
+
!recordOf(record.importsByKey, isImport) ||
|
|
138
|
+
!recordOf(record.importedClassesByKey, isClass) ||
|
|
139
|
+
!recordOf(record.views, isView) ||
|
|
140
|
+
!asJsonRecord(record.policies) ||
|
|
141
|
+
!Array.isArray(record.dependencies) ||
|
|
142
|
+
!record.dependencies.every((dependency) => {
|
|
143
|
+
const item = asJsonRecord(dependency)
|
|
144
|
+
return typeof item?.origin === 'string' && typeof item.revision === 'string'
|
|
145
|
+
}) ||
|
|
146
|
+
!('core' in record)
|
|
171
147
|
) {
|
|
172
148
|
return undefined
|
|
173
149
|
}
|
|
174
150
|
return record as unknown as SchemaIR
|
|
175
151
|
}
|
|
176
|
-
|
|
177
|
-
export function decodeIrInterfaceRecord(value: unknown): Record<string, IrInterface> | undefined {
|
|
178
|
-
const record = asJsonRecord(value)
|
|
179
|
-
if (!record || !Object.values(record).every(isInterface)) return undefined
|
|
180
|
-
return record as unknown as Record<string, IrInterface>
|
|
181
|
-
}
|