add support for daml2js to write daml-ledger code (#5550)

changelog_begin
changelog_end
This commit is contained in:
Shayne Fletcher 2020-04-14 12:14:49 -04:00 committed by GitHub
parent b3c428e76f
commit 6cd5280867
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 51 additions and 38 deletions

View File

@ -535,7 +535,7 @@ codegenTests codegenDir = testGroup "daml codegen" (
outDir = projectDir </> "generated" </> lang
when (lang == "js") $ do
let workspaces = Workspaces [makeRelative codegenDir outDir]
setupYarnEnv codegenDir workspaces [DamlTypes]
setupYarnEnv codegenDir workspaces [DamlTypes, DamlLedger]
callCommandSilent $
unwords [ "daml", "codegen", lang
, darFile ++ maybe "" ("=" ++) namespace
@ -558,7 +558,7 @@ createDamlAppTests = testGroup "create-daml-app" [gettingStartedGuideTest | not
step "Build DAML model for base application"
callCommandSilent "daml build"
step "Set up TypeScript libraries and Yarn workspaces for codegen"
setupYarnEnv tmpDir (Workspaces ["create-daml-app/daml.js"]) [DamlTypes]
setupYarnEnv tmpDir (Workspaces ["create-daml-app/daml.js"]) [DamlTypes, DamlLedger]
step "Run JavaScript codegen"
callCommandSilent "daml codegen js -o daml.js .daml/dist/create-daml-app-0.1.0.dar"
assertFileDoesNotExist (cdaDir </> "ui" </> "build" </> "index.html")
@ -589,7 +589,7 @@ createDamlAppTests = testGroup "create-daml-app" [gettingStartedGuideTest | not
step "Build the new DAML model"
callCommandSilent "daml build"
step "Set up TypeScript libraries and Yarn workspaces for codegen again"
setupYarnEnv tmpDir (Workspaces ["create-daml-app/daml.js"]) [DamlTypes]
setupYarnEnv tmpDir (Workspaces ["create-daml-app/daml.js"]) [DamlTypes, DamlLedger]
step "Run JavaScript codegen for new DAML model"
callCommandSilent "daml codegen js -o daml.js .daml/dist/create-daml-app-0.1.0.dar"
withCurrentDirectory (cdaDir </> "ui") $ do

View File

@ -55,13 +55,16 @@ cat > package.json<<EOF
"private": true,
"workspaces": ["daml2js"],
"resolutions": {
"@daml/types": "file:daml-types"
"@daml/types": "file:daml-types",
"@daml/ledger": "file:daml-ledger"
}
}
EOF
cd ~/project/daml.git
bazel build //language-support/ts/daml-types:npm_package
bazel build //language-support/ts/daml-ledger:npm_package
cp -R bazel-bin/language-support/ts/daml-types/npm_package ~/tmp/davl/daml-types
cp -R bazel-bin/language-support/ts/daml-leger/npm_package ~/tmp/davl/daml-ledger
bazel run //language-support/ts/codegen:daml2js -- -o ~/tmp/davl/daml2js ~/project/davl.git/released/*.dar
```

View File

@ -221,10 +221,11 @@ genModule pkgMap (Scope scope) curPkgId mod
, "/* eslint-disable @typescript-eslint/no-namespace */"
, "/* eslint-disable @typescript-eslint/no-use-before-define */"
, "import * as jtv from '@mojotech/json-type-validation';"
, "import * as daml from '@daml/types';"
, "import * as damlTypes from '@daml/types';"
]
-- Split the imports into the from the same package and those from another package.
-- Split the imports into those from the same package and those
-- from another package.
splitImports :: Set.Set ModuleRef -> ([ModuleName], Set.Set PackageId)
splitImports imports =
let classifyImport (pkgRef, modName) = case pkgRef of
@ -294,8 +295,8 @@ genDefDataType curPkgId conName mod tpls def =
-- of each.
assocSers = map (\(n, d) -> (n, serFromDef (drop 1) n d)) assocDefDataTypes
-- Type of the companion object.
typ' = "daml.Serializable<" <> conName <> "> & {\n" <>
T.concat (map (\n -> " " <> n <> ": daml.Serializable<" <> (conName <.> n) <> ">;\n") assocNames) <>
typ' = "damlTypes.Serializable<" <> conName <> "> & {\n" <>
T.concat (map (\n -> " " <> n <> ": damlTypes.Serializable<" <> (conName <.> n) <> ">;\n") assocNames) <>
" }"
-- Body of the companion object.
body = map (" " <>) $
@ -312,7 +313,7 @@ genDefDataType curPkgId conName mod tpls def =
typeDesc = "" : [" | '" <> cons <> "'" | cons <- cs]
-- The complete definition of the companion object.
serDesc =
["export const " <> conName <> ": daml.Serializable<" <> conName <> "> " <>
["export const " <> conName <> ": damlTypes.Serializable<" <> conName <> "> " <>
"& { readonly keys: " <> conName <> "[] } & { readonly [e in " <> conName <> "]: e } = {"] ++
[" " <> cons <> ": '" <> cons <> "'," | cons <- cs] ++
[" keys: [" <> T.concat ["'" <> cons <> "'," | cons <- cs] <> "],"] ++
@ -356,8 +357,8 @@ genDefDataType curPkgId conName mod tpls def =
(conName <.> "Key", "() => " <> snd (genType (moduleName mod) keyType) <> ".decoder()", Set.setOf typeModuleRef keyType)
templateId = unPackageId curPkgId <> ":" <> T.intercalate "." (unModuleName (moduleName mod)) <> ":" <> conName
dict =
["export const " <> conName <> ": daml.Template<" <> conName <> ", " <> keyTypeTs <> ", '" <> templateId <> "'> & {"] ++
[" " <> x <> ": daml.Choice<" <> conName <> ", " <> t <> ", " <> rtyp <> ", " <> keyTypeTs <> ">;" | (x, t, rtyp, _) <- chcs] ++
["export const " <> conName <> ": damlTypes.Template<" <> conName <> ", " <> keyTypeTs <> ", '" <> templateId <> "'> & {"] ++
[" " <> x <> ": damlTypes.Choice<" <> conName <> ", " <> t <> ", " <> rtyp <> ", " <> keyTypeTs <> ">;" | (x, t, rtyp, _) <- chcs] ++
["} = {"
] ++
[" templateId: '" <> templateId <> "',"
@ -372,9 +373,9 @@ genDefDataType curPkgId conName mod tpls def =
-- We'd write,
-- " resultDecoder: " <> rser <> ".decoder"
-- here but, consider the following scenario:
-- export const Person: daml.Template<Person>...
-- export const Person: damlTypes.Template<Person>...
-- = { ...
-- Birthday: { resultDecoder: daml.ContractId(Person).decoder, ... }
-- Birthday: { resultDecoder: damlTypes.ContractId(Person).decoder, ... }
-- ...
-- }
-- This gives rise to "error TS2454: Variable 'Person' is used before being assigned."
@ -391,7 +392,7 @@ genDefDataType curPkgId conName mod tpls def =
, "}"
]) (tplKey tpl)
registrations =
["daml.registerTemplate(" <> conName <> ");"]
["damlTypes.registerTemplate(" <> conName <> ");"]
refs = Set.unions (fieldRefs ++ keyRefs : chcRefs)
in
((makeType typeDesc, dict ++ associatedTypes ++ registrations), refs)
@ -400,10 +401,10 @@ genDefDataType curPkgId conName mod tpls def =
typeParams
| null paramNames = ""
| otherwise = "<" <> T.intercalate ", " paramNames <> ">"
serParam paramName = paramName <> ": daml.Serializable<" <> paramName <> ">"
serParam paramName = paramName <> ": damlTypes.Serializable<" <> paramName <> ">"
serHeader
| null paramNames = ": daml.Serializable<" <> conName <> "> ="
| otherwise = " = " <> typeParams <> "(" <> T.intercalate ", " (map serParam paramNames) <> "): daml.Serializable<" <> conName <> typeParams <> "> =>"
| null paramNames = ": damlTypes.Serializable<" <> conName <> "> ="
| otherwise = " = " <> typeParams <> "(" <> T.intercalate ", " (map serParam paramNames) <> "): damlTypes.Serializable<" <> conName <> typeParams <> "> =>"
makeType = onHead (\x -> "export type " <> conName <> typeParams <> " = " <> x)
makeSer serDesc =
["export const " <> conName <> serHeader <> " ({"] ++
@ -438,36 +439,36 @@ genType curModName = go
where
go = \case
TVar v -> dupe (unTypeVarName v)
TUnit -> ("{}", "daml.Unit")
TBool -> ("boolean", "daml.Bool")
TInt64 -> dupe "daml.Int"
TDecimal -> dupe "daml.Decimal"
TUnit -> ("{}", "damlTypes.Unit")
TBool -> ("boolean", "damlTypes.Bool")
TInt64 -> dupe "damlTypes.Int"
TDecimal -> dupe "damlTypes.Decimal"
TNumeric (TNat n) -> (
"daml.Numeric"
, "daml.Numeric(" <> T.pack (show (fromTypeLevelNat n :: Integer)) <> ")"
"damlTypes.Numeric"
, "damlTypes.Numeric(" <> T.pack (show (fromTypeLevelNat n :: Integer)) <> ")"
)
TText -> ("string", "daml.Text")
TTimestamp -> dupe "daml.Time"
TParty -> dupe "daml.Party"
TDate -> dupe "daml.Date"
TText -> ("string", "damlTypes.Text")
TTimestamp -> dupe "damlTypes.Time"
TParty -> dupe "damlTypes.Party"
TDate -> dupe "damlTypes.Date"
TList t ->
let (t', ser) = go t
in
(t' <> "[]", "daml.List(" <> ser <> ")")
(t' <> "[]", "damlTypes.List(" <> ser <> ")")
TOptional t ->
let (t', ser) = go t
in
("daml.Optional<" <> t' <> ">", "daml.Optional(" <> ser <> ")")
("damlTypes.Optional<" <> t' <> ">", "damlTypes.Optional(" <> ser <> ")")
TTextMap t ->
let (t', ser) = go t
in
("{ [key: string]: " <> t' <> " }", "daml.TextMap(" <> ser <> ")")
("{ [key: string]: " <> t' <> " }", "damlTypes.TextMap(" <> ser <> ")")
TUpdate _ -> error "IMPOSSIBLE: Update not serializable"
TScenario _ -> error "IMPOSSIBLE: Scenario not serializable"
TContractId t ->
let (t', ser) = go t
in
("daml.ContractId<" <> t' <> ">", "daml.ContractId(" <> ser <> ")")
("damlTypes.ContractId<" <> t' <> ">", "damlTypes.ContractId(" <> ser <> ")")
TConApp con ts ->
let (con', ser) = genTypeCon curModName con
(ts', sers) = unzip (map go ts)
@ -552,6 +553,7 @@ packageJsonDependencies :: SdkVersion -> Scope -> [Dependency] -> Value
packageJsonDependencies sdkVersion (Scope scope) dependencies = object $
[ "@mojotech/json-type-validation" .= jtvVersion
, "@daml/types" .= versionToText sdkVersion
, "@daml/ledger" .= versionToText sdkVersion
] ++
[ (scope <> "/" <> pkgName) .= ("file:../" <> pkgName) | Dependency pkgName <- dependencies ]

View File

@ -107,7 +107,7 @@ sh_test(
deps = [
"@bazel_tools//tools/bash/runfiles",
],
) if is_linux else None
) if not is_windows else None
da_haskell_library(
name = "daml2js-test-helpers",
@ -147,6 +147,7 @@ da_haskell_test(
"//:yarn",
"//compiler/damlc",
"//language-support/ts/codegen:daml2js",
"//language-support/ts/daml-ledger:npm_package",
"//language-support/ts/daml-types:npm_package",
"@davl//:released/davl-upgrade-v4-v5.dar",
"@davl//:released/davl-v4.dar",

View File

@ -228,7 +228,9 @@ tests yarn damlc daml2js davl = testGroup "daml2js tests"
, "@typescript-eslint/parser" .= typescriptEslintVersion
]
, "workspaces" .= pkgs
, "resolutions" .= object ["@daml/types" .= ("file:../daml-types" :: T.Text)]
, "resolutions" .= object
[ "@daml/types" .= ("file:../daml-types" :: T.Text)
, "@daml/ledger" .= ("file:../daml-ledger" :: T.Text)]
]
BSL.writeFile ".eslintrc.json" $ encode $
object
@ -252,7 +254,7 @@ tests yarn damlc daml2js davl = testGroup "daml2js tests"
where
setupYarnEnvironment :: IO ()
setupYarnEnvironment = do
setupYarnEnv "." (Workspaces ["daml2js"]) [DamlTypes]
setupYarnEnv "." (Workspaces ["daml2js"]) [DamlTypes, DamlLedger]
buildProject :: [String] -> IO ()
buildProject args = callProcessSilent damlc (["build"] ++ args)

View File

@ -26,6 +26,7 @@ const BOB_TOKEN = computeToken(BOB_PARTY);
const SANDBOX_PORT = 6865;
const SANDBOX_PORT_FILE = 'sandbox.port';
const JSON_API_PORT = 7575;
const JSON_API_PORT_FILE = 'json-api.port';
const HTTP_BASE_URL = `http://localhost:${JSON_API_PORT}/`;
let sandboxProcess: ChildProcess | undefined = undefined;
@ -57,8 +58,8 @@ beforeAll(async () => {
console.log('Sandbox up');
jsonApiProcess = await spawnJvmAndWaitOn(
getEnv('JSON_API'),
['--ledger-host', 'localhost', '--ledger-port', `${SANDBOX_PORT}`,'--http-port', `${JSON_API_PORT}`, '--websocket-config', 'heartBeatPer=1'],
`tcp:localhost:${JSON_API_PORT}`,
['--ledger-host', 'localhost', '--ledger-port', `${SANDBOX_PORT}`, '--port-file', JSON_API_PORT_FILE, '--http-port', `${JSON_API_PORT}`, '--websocket-config', 'heartBeatPer=1'],
`file:${JSON_API_PORT_FILE}`,
)
console.log('JSON API up');
});

View File

@ -1,7 +1,11 @@
{
"private": true,
"workspaces": ["daml2js", "build-and-lint-test"],
"workspaces": [
"daml2js",
"build-and-lint-test"
],
"resolutions": {
"@daml/types": "file:daml-types"
"@daml/types": "file:daml-types",
"@daml/ledger": "file:daml-ledger"
}
}