@platforma-sdk/tengo-builder 2.5.29 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/compiler/compiler.cjs +48 -1
  2. package/dist/compiler/compiler.cjs.map +1 -1
  3. package/dist/compiler/compiler.js +47 -1
  4. package/dist/compiler/compiler.js.map +1 -1
  5. package/dist/compiler/main.cjs +132 -6
  6. package/dist/compiler/main.cjs.map +1 -1
  7. package/dist/compiler/main.js +132 -6
  8. package/dist/compiler/main.js.map +1 -1
  9. package/dist/compiler/pack_limits.cjs +49 -0
  10. package/dist/compiler/pack_limits.cjs.map +1 -0
  11. package/dist/compiler/pack_limits.js +47 -0
  12. package/dist/compiler/pack_limits.js.map +1 -0
  13. package/dist/compiler/package.cjs.map +1 -1
  14. package/dist/compiler/package.js.map +1 -1
  15. package/dist/compiler/source.cjs +6 -2
  16. package/dist/compiler/source.cjs.map +1 -1
  17. package/dist/compiler/source.js +6 -2
  18. package/dist/compiler/source.js.map +1 -1
  19. package/dist/shared/basecmd.cjs +2 -1
  20. package/dist/shared/basecmd.cjs.map +1 -1
  21. package/dist/shared/basecmd.js +2 -1
  22. package/dist/shared/basecmd.js.map +1 -1
  23. package/dist/shared/dump.cjs +4 -0
  24. package/dist/shared/dump.cjs.map +1 -1
  25. package/dist/shared/dump.js +4 -0
  26. package/dist/shared/dump.js.map +1 -1
  27. package/package.json +5 -5
  28. package/src/compiler/compiler.test.ts +91 -0
  29. package/src/compiler/compiler.ts +72 -1
  30. package/src/compiler/main.ts +217 -11
  31. package/src/compiler/pack_limits.test.ts +173 -0
  32. package/src/compiler/pack_limits.ts +103 -0
  33. package/src/compiler/package.ts +1 -1
  34. package/src/compiler/source.test.ts +30 -0
  35. package/src/compiler/source.ts +4 -0
  36. package/src/shared/basecmd.ts +1 -1
  37. package/src/shared/dump.ts +9 -0
@@ -1 +1 @@
1
- {"version":3,"file":"source.js","names":[],"sources":["../../src/compiler/source.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport {\n type TypedArtifactName,\n type FullArtifactName,\n type ArtifactType,\n type CompileMode,\n type CompilerOption,\n fullNameToString,\n} from \"./package\";\nimport type { ArtifactMap } from \"./artifactset\";\nimport { createArtifactNameSet } from \"./artifactset\";\nimport { createHash } from \"node:crypto\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\n\n// matches any valid name in tengo. Don't forget to use '\\b' when needed to limit the boundaries!\nconst namePattern = \"[_a-zA-Z][_a-zA-Z0-9]*\";\n\nconst functionCallRE = (moduleName: string, fnName: string) => {\n return new RegExp(\n `\\\\b${moduleName}\\\\.(?<fnCall>(?<fnName>` +\n fnName +\n `)\\\\s*\\\\(\\\\s*\"(?<templateName>[^\"]+)\"\\\\s*\\\\))`,\n \"g\",\n );\n};\n\nconst functionCallLikeRE = (moduleName: string, fnName: string) => {\n return new RegExp(`\\\\b${moduleName}\\\\.(?<fnName>` + fnName + `)\\\\s*\\\\(`, \"g\");\n};\n\nexport const newGetTemplateIdRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getTemplateId\");\nexport const newGetSoftwareInfoRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getSoftwareInfo\");\n\nconst newImportTemplateRE = (moduleName: string) => functionCallRE(moduleName, \"importTemplate\");\nconst newImportTemplateDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importTemplate\");\nconst newImportSoftwareRE = (moduleName: string) => functionCallRE(moduleName, \"importSoftware\");\nconst newImportSoftwareDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importSoftware\");\nconst newImportAssetRE = (moduleName: string) => functionCallRE(moduleName, \"importAsset\");\nconst newImportAssetDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importAsset\");\n\nconst emptyLineRE = /^\\s*$/;\nconst compilerOptionRE = /^\\/\\/tengo:[\\w]/;\nconst wrongCompilerOptionRE = /^\\s*\\/\\/\\s*tengo:\\s*./;\nconst singlelineCommentRE = /^\\s*(\\/\\/)/;\nconst singlelineTerminatedCommentRE = /^\\s*\\/\\*.*\\*\\/\\s*$/; // matches '^/* ... */$' comment lines as a special case of singleline comments.\nconst multilineCommentStartRE = /^\\s*\\/\\*/;\nconst multilineCommentEndRE = /\\*\\//;\nconst multilineStatementRE = /[.,]\\s*$/; // it is hard to consistently treat (\\n\"a\"\\n) multiline statements, we forbid them for now.\n\n// import could only be an assignment in a statement,\n// other ways could break a compilation.\nconst importRE = /\\s*:=\\s*import\\s*\\(\\s*\"(?<moduleName>[^\"]+)\"\\s*\\)/;\nconst importNameRE = new RegExp(\n `\\\\b(?<importName>${namePattern}(\\\\.${namePattern})*)${importRE.source}`,\n);\nconst dependencyRE = /(?<pkgName>[^\"]+)?:(?<depID>[^\"]+)/; // use it to parse <moduleName> from importPattern or <templateName> from getTemplateID\n\n/**\n * Parse compiler option string representation\n * Compiler option line is a comment starting with '//tengo:', say\n * //tengo:hash_override tralala\n *\n * The common compiler option syntax is:\n * //tengo:<option name> [<option arg1> [<option arg 2> [...]]]\n */\nconst parseComplierOption = (opt: string): CompilerOption => {\n const parts = opt.split(\" \");\n const namePart = parts[0].split(\":\");\n if (namePart.length != 2) {\n throw new Error(\n \"compiler option format is wrong: expect to have option name after 'tengo:' prefix, like 'tengo:MyOption'\",\n );\n }\n const optName = namePart[1];\n\n return {\n name: optName,\n args: parts.slice(1),\n };\n};\n\nexport class ArtifactSource {\n constructor(\n /** The mode this artifact was built (dev or dist) */\n public readonly compileMode: CompileMode,\n /** Full artifact id, including package version */\n public readonly fullName: FullArtifactName,\n /** Hash of the source code */\n public readonly sourceHash: string,\n /** Normalized source code */\n public readonly src: string,\n /** Path to source file where artifact came from */\n public readonly srcName: string,\n /** List of dependencies */\n public readonly dependencies: TypedArtifactName[],\n /** Additional compiler options detected in source code */\n public readonly compilerOptions: CompilerOption[],\n ) {}\n}\n\nexport function parseSourceFile(\n logger: MiLogger,\n mode: CompileMode,\n srcFile: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const src = readFileSync(srcFile).toString();\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n srcFile,\n deps.array,\n opts,\n );\n}\n\nexport function parseSource(\n logger: MiLogger,\n mode: CompileMode,\n src: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n \"\",\n deps.array,\n opts,\n );\n}\n\n/**\n * Reads src\n * returns normalized source code,\n * gets dependencies from imports,\n * maps imports to global names if globalizeImports is true,\n * and collects compiler options like hashOverride.\n */\nfunction parseSourceData(\n logger: MiLogger,\n src: string,\n fullSourceName: FullArtifactName,\n globalizeImports: boolean,\n): {\n normalized: string;\n deps: ArtifactMap<TypedArtifactName>;\n opts: CompilerOption[];\n} {\n const dependencySet = createArtifactNameSet();\n const optionList: CompilerOption[] = [];\n\n // iterating over lines\n const lines = src.split(\"\\n\");\n\n // processedLines keep all the original lines from <src>.\n // If <globalizeImport>==true, the parser modifies 'import' and 'getTemplateId' lines\n // with Platforma Tengo lib and template usages, resolving local names (\":<item>\") to\n // global (\"@milaboratory/pkg:<item>\")\n const processedLines: string[] = [];\n let parserContext: sourceParserContext = {\n isInCommentBlock: false,\n canDetectOptions: true,\n artifactImportREs: new Map<string, [ArtifactType, RegExp][]>(),\n importLikeREs: new Map<string, [ArtifactType, RegExp][]>(),\n multilineStatement: \"\",\n lineNo: 0,\n };\n\n for (const line of lines) {\n parserContext.lineNo++;\n\n try {\n const {\n line: processedLine,\n context: newContext,\n artifacts,\n option,\n } = parseSingleSourceLine(logger, line, parserContext, fullSourceName.pkg, globalizeImports);\n processedLines.push(processedLine);\n parserContext = newContext;\n\n for (const artifact of artifacts ?? []) {\n dependencySet.add(artifact);\n }\n if (option) {\n optionList.push(option);\n }\n } catch (error: unknown) {\n const err = error as Error;\n throw new Error(\n `[line ${parserContext.lineNo} in ${fullNameToString(fullSourceName)}]: ${err.message}\\n\\t${line}`,\n { cause: err },\n );\n }\n }\n\n return {\n normalized: processedLines.join(\"\\n\"),\n deps: dependencySet,\n opts: optionList,\n };\n}\n\nexport type sourceParserContext = {\n isInCommentBlock: boolean;\n canDetectOptions: boolean;\n artifactImportREs: Map<string, [ArtifactType, RegExp][]>;\n importLikeREs: Map<string, [ArtifactType, RegExp][]>;\n multilineStatement: string;\n lineNo: number;\n};\n\nexport type lineProcessingResult = {\n line: string;\n context: sourceParserContext;\n artifacts: TypedArtifactName[];\n option: CompilerOption | undefined;\n};\n\nexport function parseSingleSourceLine(\n logger: MiLogger,\n line: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (context.isInCommentBlock) {\n if (multilineCommentEndRE.exec(line)) {\n context.isInCommentBlock = false;\n }\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n if (compilerOptionRE.exec(line)) {\n if (!context.canDetectOptions) {\n logger.error(\n `[line ${context.lineNo}]: compiler option '//tengo:' was detected, but it cannot be applied as compiler options can be set only at the file header, before any code line'`,\n );\n throw new Error(\n \"tengo compiler options ('//tengo:' comments) can be set only in file header\",\n );\n }\n return { line, context, artifacts: [], option: parseComplierOption(line) };\n }\n\n if (wrongCompilerOptionRE.exec(line) && context.canDetectOptions) {\n logger.warn(\n `[line ${context.lineNo}]: text simillar to compiler option ('//tengo:...') was detected, but it has wrong format. Leave it as is, if you did not mean to use a line as compiler option. Or format it to '//tengo:<option>' otherwise (no spaces between '//' and 'tengo', no spaces between ':' and option name)`,\n );\n return { line, context, artifacts: [], option: undefined };\n }\n\n if (singlelineCommentRE.test(line) || singlelineTerminatedCommentRE.test(line)) {\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const canBeInlinedComment = line.includes(\"*/\");\n if (multilineCommentStartRE.exec(line) && !canBeInlinedComment) {\n context.isInCommentBlock = true;\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const statement = context.multilineStatement + line.trim();\n\n const mayContainAComment = line.includes(\"//\") || line.includes(\"/*\");\n if (multilineStatementRE.test(line) && !mayContainAComment) {\n // We accumulate multiline statements into single line before analyzing them.\n // This dramatically simplifies parsing logic: things like\n //\n // assets.\n // importSoftware(\"a:b\");\n //\n // become simple 'assets.importSoftware(\"a:b\");' for parser checks.\n //\n // For safety reasons, we never consider anything that 'may look like a comment'\n // as a part of multiline statement to prevent joining things like\n //\n // someFnCall() // looks like multiline statement because of dot in the end of a comment.\n //\n // This problem also appears in multiline string literals, but I hope this will not\n // cause problems in real life.\n\n // We still try to process each line to globalize imports in case of complex constructions, when\n // statements are stacked one into another:\n // a.\n // use(assets.importSoftware(\":soft1\")).\n // use(assets.importSoftware(\":soft2\")).\n // run()\n // It is multiline, and it still requires import globalization mid-way, not just for the last line of statement\n const result = processAssetImport(line, statement, context, localPackageName, globalizeImports);\n context.multilineStatement += result.line.trim(); // accumulate the line after imports globalization.\n return result;\n }\n\n context.multilineStatement = \"\"; // reset accumulated multiline statement parts once we reach statement end.\n\n if (emptyLineRE.exec(statement)) {\n return { line, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n return processAssetImport(line, statement, context, localPackageName, globalizeImports);\n}\n\nfunction processModuleImport(\n importInstruction: RegExpExecArray,\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n const iInfo = parseImport(statement);\n\n // If we have plapi, ll or assets, then try to parse\n // getTemplateId, getSoftwareInfo, getSoftware and getAsset calls.\n\n if (iInfo.module === \"plapi\") {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newGetTemplateIdRE(iInfo.alias)],\n [\"software\", newGetSoftwareInfoRE(iInfo.alias)],\n ]);\n }\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:ll\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:ll\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":ll\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n ]);\n }\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:assets\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:assets\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":assets\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n [\"asset\", newImportAssetRE(iInfo.alias)],\n ]);\n context.importLikeREs.set(iInfo.module, [\n [\"template\", newImportTemplateDetector(iInfo.alias)],\n [\"software\", newImportSoftwareDetector(iInfo.alias)],\n [\"asset\", newImportAssetDetector(iInfo.alias)],\n ]);\n }\n }\n\n const artifact = parseArtifactName(iInfo.module, \"library\", localPackageName);\n if (!artifact) {\n // not a Platforma Tengo library import\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (globalizeImports) {\n originalLine = originalLine.replace(\n importInstruction[0],\n ` := import(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n\n return { line: originalLine, context, artifacts: [artifact], option: undefined };\n}\n\nfunction processAssetImport(\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (emptyLineRE.exec(statement)) {\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n const importInstruction = importRE.exec(statement);\n\n if (importInstruction) {\n return processModuleImport(\n importInstruction,\n originalLine,\n statement,\n context,\n localPackageName,\n globalizeImports,\n );\n }\n\n if (context.artifactImportREs.size > 0) {\n for (const [_, artifactRE] of context.artifactImportREs) {\n for (const [artifactType, re] of artifactRE) {\n // Find all matches in the statement\n const matches = Array.from(statement.matchAll(re));\n if (matches.length === 0) {\n continue;\n }\n\n const artifacts: TypedArtifactName[] = [];\n for (let i = matches.length - 1; i >= 0; i--) {\n const match = matches[i];\n if (!match || !match.groups) {\n continue;\n }\n\n const { fnCall, templateName, fnName } = match.groups;\n\n if (!fnCall || !templateName || !fnName) {\n throw Error(`failed to parse template import statement`);\n }\n\n const artifact = parseArtifactName(templateName, artifactType, localPackageName);\n if (!artifact) {\n throw Error(`failed to parse artifact name in ${fnName} import statement`);\n }\n artifacts.push(artifact);\n\n if (globalizeImports) {\n // Replace all occurrences of this fnCall in originalLine\n originalLine = originalLine.replaceAll(\n fnCall,\n `${fnName}(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n }\n\n return { line: originalLine, context, artifacts, option: undefined };\n }\n }\n }\n\n if (context.importLikeREs.size > 0) {\n for (const [_, artifactRE] of context.importLikeREs) {\n for (const [artifactType, re] of artifactRE) {\n const match = re.exec(statement);\n if (!match || !match.groups) {\n continue;\n }\n\n throw Error(\n `incorrect '${artifactType}' import statement: use string literal as ID (variables are not allowed) in the same line with brackets (i.e. 'importSoftware(\"sw:main\")').`,\n );\n }\n }\n }\n\n return { line: originalLine, context, artifacts: [], option: undefined };\n}\n\ninterface ImportInfo {\n module: string; // the module name without wrapping quotes: import(\"<module>\")\n alias: string; // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n}\n\nfunction parseImport(line: string): ImportInfo {\n const match = importNameRE.exec(line);\n\n if (!match || !match.groups) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n const { importName, moduleName } = match.groups;\n if (!importName || !moduleName) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n return {\n module: moduleName, // the module name without wrapping quotes: import(\"<module>\")\n alias: importName, // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n };\n}\n\nfunction parseArtifactName(\n moduleName: string,\n aType: ArtifactType,\n localPackageName: string,\n): TypedArtifactName | undefined {\n const depInfo = dependencyRE.exec(moduleName);\n if (!depInfo) {\n return;\n }\n\n if (!depInfo.groups) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n const { pkgName, depID } = depInfo.groups;\n if (!depID) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n return { type: aType, pkg: pkgName ?? localPackageName, id: depID };\n}\n\nexport function getSha256(source: string): string {\n return createHash(\"sha256\").update(source).digest(\"hex\");\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"source.js","names":[],"sources":["../../src/compiler/source.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport {\n type TypedArtifactName,\n type FullArtifactName,\n type ArtifactType,\n type CompileMode,\n type CompilerOption,\n fullNameToString,\n} from \"./package\";\nimport type { ArtifactMap } from \"./artifactset\";\nimport { createArtifactNameSet } from \"./artifactset\";\nimport { createHash } from \"node:crypto\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\n\n// matches any valid name in tengo. Don't forget to use '\\b' when needed to limit the boundaries!\nconst namePattern = \"[_a-zA-Z][_a-zA-Z0-9]*\";\n\nconst functionCallRE = (moduleName: string, fnName: string) => {\n return new RegExp(\n `\\\\b${moduleName}\\\\.(?<fnCall>(?<fnName>` +\n fnName +\n `)\\\\s*\\\\(\\\\s*\"(?<templateName>[^\"]+)\"\\\\s*\\\\))`,\n \"g\",\n );\n};\n\nconst functionCallLikeRE = (moduleName: string, fnName: string) => {\n return new RegExp(`\\\\b${moduleName}\\\\.(?<fnName>` + fnName + `)\\\\s*\\\\(`, \"g\");\n};\n\nexport const newGetTemplateIdRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getTemplateId\");\nexport const newGetSoftwareInfoRE = (moduleName: string) =>\n functionCallRE(moduleName, \"getSoftwareInfo\");\n\nconst newImportTemplateRE = (moduleName: string) => functionCallRE(moduleName, \"importTemplate\");\nconst newImportTemplateDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importTemplate\");\nconst newImportSoftwareRE = (moduleName: string) => functionCallRE(moduleName, \"importSoftware\");\nconst newImportSoftwareDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importSoftware\");\nconst newImportAssetRE = (moduleName: string) => functionCallRE(moduleName, \"importAsset\");\nconst newImportAssetDetector = (moduleName: string) =>\n functionCallLikeRE(moduleName, \"importAsset\");\nconst newImportWasmRE = (moduleName: string) => functionCallRE(moduleName, \"importWasm\");\nconst newImportWasmDetector = (moduleName: string) => functionCallLikeRE(moduleName, \"importWasm\");\n\nconst emptyLineRE = /^\\s*$/;\nconst compilerOptionRE = /^\\/\\/tengo:[\\w]/;\nconst wrongCompilerOptionRE = /^\\s*\\/\\/\\s*tengo:\\s*./;\nconst singlelineCommentRE = /^\\s*(\\/\\/)/;\nconst singlelineTerminatedCommentRE = /^\\s*\\/\\*.*\\*\\/\\s*$/; // matches '^/* ... */$' comment lines as a special case of singleline comments.\nconst multilineCommentStartRE = /^\\s*\\/\\*/;\nconst multilineCommentEndRE = /\\*\\//;\nconst multilineStatementRE = /[.,]\\s*$/; // it is hard to consistently treat (\\n\"a\"\\n) multiline statements, we forbid them for now.\n\n// import could only be an assignment in a statement,\n// other ways could break a compilation.\nconst importRE = /\\s*:=\\s*import\\s*\\(\\s*\"(?<moduleName>[^\"]+)\"\\s*\\)/;\nconst importNameRE = new RegExp(\n `\\\\b(?<importName>${namePattern}(\\\\.${namePattern})*)${importRE.source}`,\n);\nconst dependencyRE = /(?<pkgName>[^\"]+)?:(?<depID>[^\"]+)/; // use it to parse <moduleName> from importPattern or <templateName> from getTemplateID\n\n/**\n * Parse compiler option string representation\n * Compiler option line is a comment starting with '//tengo:', say\n * //tengo:hash_override tralala\n *\n * The common compiler option syntax is:\n * //tengo:<option name> [<option arg1> [<option arg 2> [...]]]\n */\nconst parseComplierOption = (opt: string): CompilerOption => {\n const parts = opt.split(\" \");\n const namePart = parts[0].split(\":\");\n if (namePart.length != 2) {\n throw new Error(\n \"compiler option format is wrong: expect to have option name after 'tengo:' prefix, like 'tengo:MyOption'\",\n );\n }\n const optName = namePart[1];\n\n return {\n name: optName,\n args: parts.slice(1),\n };\n};\n\nexport class ArtifactSource {\n constructor(\n /** The mode this artifact was built (dev or dist) */\n public readonly compileMode: CompileMode,\n /** Full artifact id, including package version */\n public readonly fullName: FullArtifactName,\n /** Hash of the source code */\n public readonly sourceHash: string,\n /** Normalized source code */\n public readonly src: string,\n /** Path to source file where artifact came from */\n public readonly srcName: string,\n /** List of dependencies */\n public readonly dependencies: TypedArtifactName[],\n /** Additional compiler options detected in source code */\n public readonly compilerOptions: CompilerOption[],\n ) {}\n}\n\nexport function parseSourceFile(\n logger: MiLogger,\n mode: CompileMode,\n srcFile: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const src = readFileSync(srcFile).toString();\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n srcFile,\n deps.array,\n opts,\n );\n}\n\nexport function parseSource(\n logger: MiLogger,\n mode: CompileMode,\n src: string,\n fullSourceName: FullArtifactName,\n normalize: boolean,\n): ArtifactSource {\n const { deps, normalized, opts } = parseSourceData(logger, src, fullSourceName, normalize);\n\n return new ArtifactSource(\n mode,\n fullSourceName,\n getSha256(normalized),\n normalized,\n \"\",\n deps.array,\n opts,\n );\n}\n\n/**\n * Reads src\n * returns normalized source code,\n * gets dependencies from imports,\n * maps imports to global names if globalizeImports is true,\n * and collects compiler options like hashOverride.\n */\nfunction parseSourceData(\n logger: MiLogger,\n src: string,\n fullSourceName: FullArtifactName,\n globalizeImports: boolean,\n): {\n normalized: string;\n deps: ArtifactMap<TypedArtifactName>;\n opts: CompilerOption[];\n} {\n const dependencySet = createArtifactNameSet();\n const optionList: CompilerOption[] = [];\n\n // iterating over lines\n const lines = src.split(\"\\n\");\n\n // processedLines keep all the original lines from <src>.\n // If <globalizeImport>==true, the parser modifies 'import' and 'getTemplateId' lines\n // with Platforma Tengo lib and template usages, resolving local names (\":<item>\") to\n // global (\"@milaboratory/pkg:<item>\")\n const processedLines: string[] = [];\n let parserContext: sourceParserContext = {\n isInCommentBlock: false,\n canDetectOptions: true,\n artifactImportREs: new Map<string, [ArtifactType, RegExp][]>(),\n importLikeREs: new Map<string, [ArtifactType, RegExp][]>(),\n multilineStatement: \"\",\n lineNo: 0,\n };\n\n for (const line of lines) {\n parserContext.lineNo++;\n\n try {\n const {\n line: processedLine,\n context: newContext,\n artifacts,\n option,\n } = parseSingleSourceLine(logger, line, parserContext, fullSourceName.pkg, globalizeImports);\n processedLines.push(processedLine);\n parserContext = newContext;\n\n for (const artifact of artifacts ?? []) {\n dependencySet.add(artifact);\n }\n if (option) {\n optionList.push(option);\n }\n } catch (error: unknown) {\n const err = error as Error;\n throw new Error(\n `[line ${parserContext.lineNo} in ${fullNameToString(fullSourceName)}]: ${err.message}\\n\\t${line}`,\n { cause: err },\n );\n }\n }\n\n return {\n normalized: processedLines.join(\"\\n\"),\n deps: dependencySet,\n opts: optionList,\n };\n}\n\nexport type sourceParserContext = {\n isInCommentBlock: boolean;\n canDetectOptions: boolean;\n artifactImportREs: Map<string, [ArtifactType, RegExp][]>;\n importLikeREs: Map<string, [ArtifactType, RegExp][]>;\n multilineStatement: string;\n lineNo: number;\n};\n\nexport type lineProcessingResult = {\n line: string;\n context: sourceParserContext;\n artifacts: TypedArtifactName[];\n option: CompilerOption | undefined;\n};\n\nexport function parseSingleSourceLine(\n logger: MiLogger,\n line: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (context.isInCommentBlock) {\n if (multilineCommentEndRE.exec(line)) {\n context.isInCommentBlock = false;\n }\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n if (compilerOptionRE.exec(line)) {\n if (!context.canDetectOptions) {\n logger.error(\n `[line ${context.lineNo}]: compiler option '//tengo:' was detected, but it cannot be applied as compiler options can be set only at the file header, before any code line'`,\n );\n throw new Error(\n \"tengo compiler options ('//tengo:' comments) can be set only in file header\",\n );\n }\n return { line, context, artifacts: [], option: parseComplierOption(line) };\n }\n\n if (wrongCompilerOptionRE.exec(line) && context.canDetectOptions) {\n logger.warn(\n `[line ${context.lineNo}]: text simillar to compiler option ('//tengo:...') was detected, but it has wrong format. Leave it as is, if you did not mean to use a line as compiler option. Or format it to '//tengo:<option>' otherwise (no spaces between '//' and 'tengo', no spaces between ':' and option name)`,\n );\n return { line, context, artifacts: [], option: undefined };\n }\n\n if (singlelineCommentRE.test(line) || singlelineTerminatedCommentRE.test(line)) {\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const canBeInlinedComment = line.includes(\"*/\");\n if (multilineCommentStartRE.exec(line) && !canBeInlinedComment) {\n context.isInCommentBlock = true;\n return { line: \"\", context, artifacts: [], option: undefined };\n }\n\n const statement = context.multilineStatement + line.trim();\n\n const mayContainAComment = line.includes(\"//\") || line.includes(\"/*\");\n if (multilineStatementRE.test(line) && !mayContainAComment) {\n // We accumulate multiline statements into single line before analyzing them.\n // This dramatically simplifies parsing logic: things like\n //\n // assets.\n // importSoftware(\"a:b\");\n //\n // become simple 'assets.importSoftware(\"a:b\");' for parser checks.\n //\n // For safety reasons, we never consider anything that 'may look like a comment'\n // as a part of multiline statement to prevent joining things like\n //\n // someFnCall() // looks like multiline statement because of dot in the end of a comment.\n //\n // This problem also appears in multiline string literals, but I hope this will not\n // cause problems in real life.\n\n // We still try to process each line to globalize imports in case of complex constructions, when\n // statements are stacked one into another:\n // a.\n // use(assets.importSoftware(\":soft1\")).\n // use(assets.importSoftware(\":soft2\")).\n // run()\n // It is multiline, and it still requires import globalization mid-way, not just for the last line of statement\n const result = processAssetImport(line, statement, context, localPackageName, globalizeImports);\n context.multilineStatement += result.line.trim(); // accumulate the line after imports globalization.\n return result;\n }\n\n context.multilineStatement = \"\"; // reset accumulated multiline statement parts once we reach statement end.\n\n if (emptyLineRE.exec(statement)) {\n return { line, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n return processAssetImport(line, statement, context, localPackageName, globalizeImports);\n}\n\nfunction processModuleImport(\n importInstruction: RegExpExecArray,\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n const iInfo = parseImport(statement);\n\n // If we have plapi, ll or assets, then try to parse\n // getTemplateId, getSoftwareInfo, getSoftware and getAsset calls.\n\n if (iInfo.module === \"plapi\") {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newGetTemplateIdRE(iInfo.alias)],\n [\"software\", newGetSoftwareInfoRE(iInfo.alias)],\n ]);\n }\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:ll\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:ll\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":ll\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n ]);\n }\n }\n\n if (\n iInfo.module === \"@milaboratory/tengo-sdk:assets\" ||\n iInfo.module === \"@platforma-sdk/workflow-tengo:assets\" ||\n ((localPackageName === \"@milaboratory/tengo-sdk\" ||\n localPackageName === \"@platforma-sdk/workflow-tengo\") &&\n iInfo.module === \":assets\")\n ) {\n if (!context.artifactImportREs.has(iInfo.module)) {\n context.artifactImportREs.set(iInfo.module, [\n [\"template\", newImportTemplateRE(iInfo.alias)],\n [\"software\", newImportSoftwareRE(iInfo.alias)],\n [\"asset\", newImportAssetRE(iInfo.alias)],\n [\"wasm\", newImportWasmRE(iInfo.alias)],\n ]);\n context.importLikeREs.set(iInfo.module, [\n [\"template\", newImportTemplateDetector(iInfo.alias)],\n [\"software\", newImportSoftwareDetector(iInfo.alias)],\n [\"asset\", newImportAssetDetector(iInfo.alias)],\n [\"wasm\", newImportWasmDetector(iInfo.alias)],\n ]);\n }\n }\n\n const artifact = parseArtifactName(iInfo.module, \"library\", localPackageName);\n if (!artifact) {\n // not a Platforma Tengo library import\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n if (globalizeImports) {\n originalLine = originalLine.replace(\n importInstruction[0],\n ` := import(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n\n return { line: originalLine, context, artifacts: [artifact], option: undefined };\n}\n\nfunction processAssetImport(\n originalLine: string,\n statement: string,\n context: sourceParserContext,\n localPackageName: string,\n globalizeImports?: boolean,\n): lineProcessingResult {\n if (emptyLineRE.exec(statement)) {\n return { line: originalLine, context, artifacts: [], option: undefined };\n }\n\n // options could be only at the top of the file.\n context.canDetectOptions = false;\n\n const importInstruction = importRE.exec(statement);\n\n if (importInstruction) {\n return processModuleImport(\n importInstruction,\n originalLine,\n statement,\n context,\n localPackageName,\n globalizeImports,\n );\n }\n\n if (context.artifactImportREs.size > 0) {\n for (const [_, artifactRE] of context.artifactImportREs) {\n for (const [artifactType, re] of artifactRE) {\n // Find all matches in the statement\n const matches = Array.from(statement.matchAll(re));\n if (matches.length === 0) {\n continue;\n }\n\n const artifacts: TypedArtifactName[] = [];\n for (let i = matches.length - 1; i >= 0; i--) {\n const match = matches[i];\n if (!match || !match.groups) {\n continue;\n }\n\n const { fnCall, templateName, fnName } = match.groups;\n\n if (!fnCall || !templateName || !fnName) {\n throw Error(`failed to parse template import statement`);\n }\n\n const artifact = parseArtifactName(templateName, artifactType, localPackageName);\n if (!artifact) {\n throw Error(`failed to parse artifact name in ${fnName} import statement`);\n }\n artifacts.push(artifact);\n\n if (globalizeImports) {\n // Replace all occurrences of this fnCall in originalLine\n originalLine = originalLine.replaceAll(\n fnCall,\n `${fnName}(\"${artifact.pkg}:${artifact.id}\")`,\n );\n }\n }\n\n return { line: originalLine, context, artifacts, option: undefined };\n }\n }\n }\n\n if (context.importLikeREs.size > 0) {\n for (const [_, artifactRE] of context.importLikeREs) {\n for (const [artifactType, re] of artifactRE) {\n const match = re.exec(statement);\n if (!match || !match.groups) {\n continue;\n }\n\n throw Error(\n `incorrect '${artifactType}' import statement: use string literal as ID (variables are not allowed) in the same line with brackets (i.e. 'importSoftware(\"sw:main\")').`,\n );\n }\n }\n }\n\n return { line: originalLine, context, artifacts: [], option: undefined };\n}\n\ninterface ImportInfo {\n module: string; // the module name without wrapping quotes: import(\"<module>\")\n alias: string; // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n}\n\nfunction parseImport(line: string): ImportInfo {\n const match = importNameRE.exec(line);\n\n if (!match || !match.groups) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n const { importName, moduleName } = match.groups;\n if (!importName || !moduleName) {\n throw Error(`failed to parse 'import' statement`);\n }\n\n return {\n module: moduleName, // the module name without wrapping quotes: import(\"<module>\")\n alias: importName, // the name of variable that keeps imported module: <alias> := import(\"<module>\")\n };\n}\n\nfunction parseArtifactName(\n moduleName: string,\n aType: ArtifactType,\n localPackageName: string,\n): TypedArtifactName | undefined {\n const depInfo = dependencyRE.exec(moduleName);\n if (!depInfo) {\n return;\n }\n\n if (!depInfo.groups) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n const { pkgName, depID } = depInfo.groups;\n if (!depID) {\n throw Error(\n `failed to parse dependency name inside 'import' statement. The dependency name should have format '<package>:<templateName>'`,\n );\n }\n\n return { type: aType, pkg: pkgName ?? localPackageName, id: depID };\n}\n\nexport function getSha256(source: string): string {\n return createHash(\"sha256\").update(source).digest(\"hex\");\n}\n"],"mappings":"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"}
@@ -36,7 +36,8 @@ const ArtifactTypeFlag = { type: _oclif_core.Flags.string({
36
36
  "template",
37
37
  "test",
38
38
  "software",
39
- "asset"
39
+ "asset",
40
+ "wasm"
40
41
  ],
41
42
  default: "all"
42
43
  }) };
@@ -1 +1 @@
1
- {"version":3,"file":"basecmd.cjs","names":["Flags"],"sources":["../../src/shared/basecmd.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\n\nexport const GlobalFlags = {\n \"log-level\": Flags.string({\n description: \"logging level\",\n default: \"info\",\n options: [\"error\", \"warn\", \"info\", \"debug\"],\n }),\n};\n\nexport const CtagsFlags = {\n \"generate-tags\": Flags.boolean({\n description: \"generate tags, default false\",\n default: false,\n }),\n\n \"tags-file\": Flags.file({\n description: 'where to put \".tags\" file, it should be a root of VS Code project',\n default: \"../../.tags\", // usually a user opens a directory with all blocks\n }),\n\n \"tags-additional-args\": Flags.string({\n description: \"additional flags for universal-ctags command: e.g. -e for emacs\",\n default: [],\n multiple: true,\n delimiter: \",\",\n }),\n};\n\nexport const ArtifactTypeFlag = {\n type: Flags.string({\n aliases: [\"t\"],\n description: \"artifact type\",\n options: [\"all\", \"library\", \"template\", \"test\", \"software\", \"asset\"],\n default: \"all\",\n }),\n};\n"],"mappings":";;;AAEA,MAAa,cAAc,EACzB,aAAaA,YAAAA,MAAM,OAAO;CACxB,aAAa;CACb,SAAS;CACT,SAAS;EAAC;EAAS;EAAQ;EAAQ;EAAQ;CAC5C,CAAC,EACH;AAED,MAAa,aAAa;CACxB,iBAAiBA,YAAAA,MAAM,QAAQ;EAC7B,aAAa;EACb,SAAS;EACV,CAAC;CAEF,aAAaA,YAAAA,MAAM,KAAK;EACtB,aAAa;EACb,SAAS;EACV,CAAC;CAEF,wBAAwBA,YAAAA,MAAM,OAAO;EACnC,aAAa;EACb,SAAS,EAAE;EACX,UAAU;EACV,WAAW;EACZ,CAAC;CACH;AAED,MAAa,mBAAmB,EAC9B,MAAMA,YAAAA,MAAM,OAAO;CACjB,SAAS,CAAC,IAAI;CACd,aAAa;CACb,SAAS;EAAC;EAAO;EAAW;EAAY;EAAQ;EAAY;EAAQ;CACpE,SAAS;CACV,CAAC,EACH"}
1
+ {"version":3,"file":"basecmd.cjs","names":["Flags"],"sources":["../../src/shared/basecmd.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\n\nexport const GlobalFlags = {\n \"log-level\": Flags.string({\n description: \"logging level\",\n default: \"info\",\n options: [\"error\", \"warn\", \"info\", \"debug\"],\n }),\n};\n\nexport const CtagsFlags = {\n \"generate-tags\": Flags.boolean({\n description: \"generate tags, default false\",\n default: false,\n }),\n\n \"tags-file\": Flags.file({\n description: 'where to put \".tags\" file, it should be a root of VS Code project',\n default: \"../../.tags\", // usually a user opens a directory with all blocks\n }),\n\n \"tags-additional-args\": Flags.string({\n description: \"additional flags for universal-ctags command: e.g. -e for emacs\",\n default: [],\n multiple: true,\n delimiter: \",\",\n }),\n};\n\nexport const ArtifactTypeFlag = {\n type: Flags.string({\n aliases: [\"t\"],\n description: \"artifact type\",\n options: [\"all\", \"library\", \"template\", \"test\", \"software\", \"asset\", \"wasm\"],\n default: \"all\",\n }),\n};\n"],"mappings":";;;AAEA,MAAa,cAAc,EACzB,aAAaA,YAAAA,MAAM,OAAO;CACxB,aAAa;CACb,SAAS;CACT,SAAS;EAAC;EAAS;EAAQ;EAAQ;EAAQ;CAC5C,CAAC,EACH;AAED,MAAa,aAAa;CACxB,iBAAiBA,YAAAA,MAAM,QAAQ;EAC7B,aAAa;EACb,SAAS;EACV,CAAC;CAEF,aAAaA,YAAAA,MAAM,KAAK;EACtB,aAAa;EACb,SAAS;EACV,CAAC;CAEF,wBAAwBA,YAAAA,MAAM,OAAO;EACnC,aAAa;EACb,SAAS,EAAE;EACX,UAAU;EACV,WAAW;EACZ,CAAC;CACH;AAED,MAAa,mBAAmB,EAC9B,MAAMA,YAAAA,MAAM,OAAO;CACjB,SAAS,CAAC,IAAI;CACd,aAAa;CACb,SAAS;EAAC;EAAO;EAAW;EAAY;EAAQ;EAAY;EAAS;EAAO;CAC5E,SAAS;CACV,CAAC,EACH"}
@@ -35,7 +35,8 @@ const ArtifactTypeFlag = { type: Flags.string({
35
35
  "template",
36
36
  "test",
37
37
  "software",
38
- "asset"
38
+ "asset",
39
+ "wasm"
39
40
  ],
40
41
  default: "all"
41
42
  }) };
@@ -1 +1 @@
1
- {"version":3,"file":"basecmd.js","names":[],"sources":["../../src/shared/basecmd.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\n\nexport const GlobalFlags = {\n \"log-level\": Flags.string({\n description: \"logging level\",\n default: \"info\",\n options: [\"error\", \"warn\", \"info\", \"debug\"],\n }),\n};\n\nexport const CtagsFlags = {\n \"generate-tags\": Flags.boolean({\n description: \"generate tags, default false\",\n default: false,\n }),\n\n \"tags-file\": Flags.file({\n description: 'where to put \".tags\" file, it should be a root of VS Code project',\n default: \"../../.tags\", // usually a user opens a directory with all blocks\n }),\n\n \"tags-additional-args\": Flags.string({\n description: \"additional flags for universal-ctags command: e.g. -e for emacs\",\n default: [],\n multiple: true,\n delimiter: \",\",\n }),\n};\n\nexport const ArtifactTypeFlag = {\n type: Flags.string({\n aliases: [\"t\"],\n description: \"artifact type\",\n options: [\"all\", \"library\", \"template\", \"test\", \"software\", \"asset\"],\n default: \"all\",\n }),\n};\n"],"mappings":";;AAEA,MAAa,cAAc,EACzB,aAAa,MAAM,OAAO;CACxB,aAAa;CACb,SAAS;CACT,SAAS;EAAC;EAAS;EAAQ;EAAQ;EAAQ;CAC5C,CAAC,EACH;AAED,MAAa,aAAa;CACxB,iBAAiB,MAAM,QAAQ;EAC7B,aAAa;EACb,SAAS;EACV,CAAC;CAEF,aAAa,MAAM,KAAK;EACtB,aAAa;EACb,SAAS;EACV,CAAC;CAEF,wBAAwB,MAAM,OAAO;EACnC,aAAa;EACb,SAAS,EAAE;EACX,UAAU;EACV,WAAW;EACZ,CAAC;CACH;AAED,MAAa,mBAAmB,EAC9B,MAAM,MAAM,OAAO;CACjB,SAAS,CAAC,IAAI;CACd,aAAa;CACb,SAAS;EAAC;EAAO;EAAW;EAAY;EAAQ;EAAY;EAAQ;CACpE,SAAS;CACV,CAAC,EACH"}
1
+ {"version":3,"file":"basecmd.js","names":[],"sources":["../../src/shared/basecmd.ts"],"sourcesContent":["import { Flags } from \"@oclif/core\";\n\nexport const GlobalFlags = {\n \"log-level\": Flags.string({\n description: \"logging level\",\n default: \"info\",\n options: [\"error\", \"warn\", \"info\", \"debug\"],\n }),\n};\n\nexport const CtagsFlags = {\n \"generate-tags\": Flags.boolean({\n description: \"generate tags, default false\",\n default: false,\n }),\n\n \"tags-file\": Flags.file({\n description: 'where to put \".tags\" file, it should be a root of VS Code project',\n default: \"../../.tags\", // usually a user opens a directory with all blocks\n }),\n\n \"tags-additional-args\": Flags.string({\n description: \"additional flags for universal-ctags command: e.g. -e for emacs\",\n default: [],\n multiple: true,\n delimiter: \",\",\n }),\n};\n\nexport const ArtifactTypeFlag = {\n type: Flags.string({\n aliases: [\"t\"],\n description: \"artifact type\",\n options: [\"all\", \"library\", \"template\", \"test\", \"software\", \"asset\", \"wasm\"],\n default: \"all\",\n }),\n};\n"],"mappings":";;AAEA,MAAa,cAAc,EACzB,aAAa,MAAM,OAAO;CACxB,aAAa;CACb,SAAS;CACT,SAAS;EAAC;EAAS;EAAQ;EAAQ;EAAQ;CAC5C,CAAC,EACH;AAED,MAAa,aAAa;CACxB,iBAAiB,MAAM,QAAQ;EAC7B,aAAa;EACb,SAAS;EACV,CAAC;CAEF,aAAa,MAAM,KAAK;EACtB,aAAa;EACb,SAAS;EACV,CAAC;CAEF,wBAAwB,MAAM,OAAO;EACnC,aAAa;EACb,SAAS,EAAE;EACX,UAAU;EACV,WAAW;EACZ,CAAC;CACH;AAED,MAAa,mBAAmB,EAC9B,MAAM,MAAM,OAAO;CACjB,SAAS,CAAC,IAAI;CACd,aAAa;CACb,SAAS;EAAC;EAAO;EAAW;EAAY;EAAQ;EAAY;EAAS;EAAO;CAC5E,SAAS;CACV,CAAC,EACH"}
@@ -45,6 +45,10 @@ function dumpArtifacts(logger, stream, aType) {
45
45
  stream.write(JSON.stringify(src) + "\n");
46
46
  }
47
47
  }
48
+ if (!aType || aType === "wasm") for (const wasm of compiler.allWasm()) {
49
+ logger.debug(`Dumping to pl-tester: ${require_package.typedArtifactNameToString(wasm.fullName)}`);
50
+ stream.write(JSON.stringify(wasm) + "\n");
51
+ }
48
52
  if (!aType || aType === "test") {
49
53
  for (const src of sources) if (src.fullName.type === "test") {
50
54
  logger.debug(`Dumping to pl-tester: ${require_package.typedArtifactNameToString(src.fullName)} ${src.srcName}`);
@@ -1 +1 @@
1
- {"version":3,"file":"dump.cjs","names":["getPackageInfo","parseSources","newCompiler","typedArtifactNameToString","compile"],"sources":["../../src/shared/dump.ts"],"sourcesContent":["import type winston from \"winston\";\nimport { getPackageInfo, newCompiler, compile, parseSources } from \"../compiler/main\";\nimport type { ArtifactType } from \"../compiler/package\";\nimport { typedArtifactNameToString } from \"../compiler/package\";\nimport type { TemplateDataV3 } from \"@milaboratories/pl-model-backend\";\n\nexport function dumpArtifacts(\n logger: winston.Logger,\n stream: NodeJS.WritableStream,\n aType?: ArtifactType,\n): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n\n const sources = parseSources(logger, packageInfo, \"dist\", \"src\", \"\");\n\n const compiler = newCompiler(logger, packageInfo, \"dist\");\n\n // group output by type:\n // - all libs\n // - all templates\n // - all software\n // - all assets\n // - all tests\n\n // Libs\n\n if (!aType || aType === \"library\") {\n for (const lib of compiler.allLibs()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(lib.fullName)}`);\n stream.write(JSON.stringify(lib) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Templates\n\n if (!aType || aType === \"template\") {\n for (const tpl of compiler.allTemplates()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(tpl.fullName)}`);\n stream.write(JSON.stringify(tpl) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"template\") {\n logger.debug(\n `Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)} ${src.srcName}`,\n );\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Software\n\n if (!aType || aType === \"software\") {\n for (const sw of compiler.allSoftware()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(sw.fullName)}`);\n stream.write(JSON.stringify(sw) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"software\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Assets\n\n if (!aType || aType === \"asset\") {\n for (const asset of compiler.allAssets()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(asset.fullName)}`);\n stream.write(JSON.stringify(asset) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"asset\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Tests\n\n if (!aType || aType === \"test\") {\n for (const src of sources) {\n if (src.fullName.type === \"test\") {\n logger.debug(\n `Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)} ${src.srcName}`,\n );\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n}\n\nexport function dumpLibs(\n logger: winston.Logger,\n stream: NodeJS.WritableStream,\n recursive: boolean,\n): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n\n const sources = parseSources(logger, packageInfo, \"dist\", \"src\", \"\");\n\n if (!recursive) {\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n\n return;\n }\n\n const compiler = newCompiler(logger, packageInfo, \"dist\");\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n compiler.addLib(src);\n }\n }\n\n for (const lib of compiler.allLibs()) {\n stream.write(JSON.stringify(lib) + \"\\n\");\n }\n}\n\nexport function dumpSoftware(logger: winston.Logger, stream: NodeJS.WritableStream): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n const compiled = compile(logger, packageInfo, \"dist\");\n\n const hashes = new Set<string>();\n const sourceMap = new Map<string, string>();\n for (const tpl of compiled.templates) {\n Object.entries(tpl.data.hashToSource).forEach(([hash, src]) => sourceMap.set(hash, src));\n getTemplateSoftware(tpl.data.template).forEach((hash) => hashes.add(hash));\n }\n\n for (const hash of hashes) {\n const src = sourceMap.get(hash);\n if (src) {\n if (Object.hasOwn(JSON.parse(src) as object, \"asset\")) {\n // Skip assets. They are kept in templates software because of backward compatibility with backend.\n continue;\n }\n stream.write(src);\n if (!src.endsWith(\"\\n\")) {\n stream.write(\"\\n\");\n }\n } else {\n throw new Error(`Source not found for hash: ${hash}`);\n }\n }\n}\n\nfunction getTemplateSoftware(tpl: TemplateDataV3): Set<string> {\n const hashes = new Set<string>();\n for (const sw of Object.values(tpl.software)) {\n hashes.add(sw.sourceHash);\n }\n for (const subTpl of Object.values(tpl.templates)) {\n getTemplateSoftware(subTpl).forEach((hash) => hashes.add(hash));\n }\n\n return new Set(hashes);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"dump.cjs","names":["getPackageInfo","parseSources","newCompiler","typedArtifactNameToString","compile"],"sources":["../../src/shared/dump.ts"],"sourcesContent":["import type winston from \"winston\";\nimport { getPackageInfo, newCompiler, compile, parseSources } from \"../compiler/main\";\nimport type { ArtifactType } from \"../compiler/package\";\nimport { typedArtifactNameToString } from \"../compiler/package\";\nimport type { TemplateDataV3 } from \"@milaboratories/pl-model-backend\";\n\nexport function dumpArtifacts(\n logger: winston.Logger,\n stream: NodeJS.WritableStream,\n aType?: ArtifactType,\n): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n\n const sources = parseSources(logger, packageInfo, \"dist\", \"src\", \"\");\n\n const compiler = newCompiler(logger, packageInfo, \"dist\");\n\n // group output by type:\n // - all libs\n // - all templates\n // - all software\n // - all assets\n // - all tests\n\n // Libs\n\n if (!aType || aType === \"library\") {\n for (const lib of compiler.allLibs()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(lib.fullName)}`);\n stream.write(JSON.stringify(lib) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Templates\n\n if (!aType || aType === \"template\") {\n for (const tpl of compiler.allTemplates()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(tpl.fullName)}`);\n stream.write(JSON.stringify(tpl) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"template\") {\n logger.debug(\n `Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)} ${src.srcName}`,\n );\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Software\n\n if (!aType || aType === \"software\") {\n for (const sw of compiler.allSoftware()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(sw.fullName)}`);\n stream.write(JSON.stringify(sw) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"software\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Assets\n\n if (!aType || aType === \"asset\") {\n for (const asset of compiler.allAssets()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(asset.fullName)}`);\n stream.write(JSON.stringify(asset) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"asset\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Wasm\n\n if (!aType || aType === \"wasm\") {\n for (const wasm of compiler.allWasm()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(wasm.fullName)}`);\n stream.write(JSON.stringify(wasm) + \"\\n\");\n }\n }\n\n // Tests\n\n if (!aType || aType === \"test\") {\n for (const src of sources) {\n if (src.fullName.type === \"test\") {\n logger.debug(\n `Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)} ${src.srcName}`,\n );\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n}\n\nexport function dumpLibs(\n logger: winston.Logger,\n stream: NodeJS.WritableStream,\n recursive: boolean,\n): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n\n const sources = parseSources(logger, packageInfo, \"dist\", \"src\", \"\");\n\n if (!recursive) {\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n\n return;\n }\n\n const compiler = newCompiler(logger, packageInfo, \"dist\");\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n compiler.addLib(src);\n }\n }\n\n for (const lib of compiler.allLibs()) {\n stream.write(JSON.stringify(lib) + \"\\n\");\n }\n}\n\nexport function dumpSoftware(logger: winston.Logger, stream: NodeJS.WritableStream): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n const compiled = compile(logger, packageInfo, \"dist\");\n\n const hashes = new Set<string>();\n const sourceMap = new Map<string, string>();\n for (const tpl of compiled.templates) {\n Object.entries(tpl.data.hashToSource).forEach(([hash, src]) => sourceMap.set(hash, src));\n getTemplateSoftware(tpl.data.template).forEach((hash) => hashes.add(hash));\n }\n\n for (const hash of hashes) {\n const src = sourceMap.get(hash);\n if (src) {\n if (Object.hasOwn(JSON.parse(src) as object, \"asset\")) {\n // Skip assets. They are kept in templates software because of backward compatibility with backend.\n continue;\n }\n stream.write(src);\n if (!src.endsWith(\"\\n\")) {\n stream.write(\"\\n\");\n }\n } else {\n throw new Error(`Source not found for hash: ${hash}`);\n }\n }\n}\n\nfunction getTemplateSoftware(tpl: TemplateDataV3): Set<string> {\n const hashes = new Set<string>();\n for (const sw of Object.values(tpl.software)) {\n hashes.add(sw.sourceHash);\n }\n for (const subTpl of Object.values(tpl.templates)) {\n getTemplateSoftware(subTpl).forEach((hash) => hashes.add(hash));\n }\n\n return new Set(hashes);\n}\n"],"mappings":"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"}
@@ -45,6 +45,10 @@ function dumpArtifacts(logger, stream, aType) {
45
45
  stream.write(JSON.stringify(src) + "\n");
46
46
  }
47
47
  }
48
+ if (!aType || aType === "wasm") for (const wasm of compiler.allWasm()) {
49
+ logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(wasm.fullName)}`);
50
+ stream.write(JSON.stringify(wasm) + "\n");
51
+ }
48
52
  if (!aType || aType === "test") {
49
53
  for (const src of sources) if (src.fullName.type === "test") {
50
54
  logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)} ${src.srcName}`);
@@ -1 +1 @@
1
- {"version":3,"file":"dump.js","names":[],"sources":["../../src/shared/dump.ts"],"sourcesContent":["import type winston from \"winston\";\nimport { getPackageInfo, newCompiler, compile, parseSources } from \"../compiler/main\";\nimport type { ArtifactType } from \"../compiler/package\";\nimport { typedArtifactNameToString } from \"../compiler/package\";\nimport type { TemplateDataV3 } from \"@milaboratories/pl-model-backend\";\n\nexport function dumpArtifacts(\n logger: winston.Logger,\n stream: NodeJS.WritableStream,\n aType?: ArtifactType,\n): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n\n const sources = parseSources(logger, packageInfo, \"dist\", \"src\", \"\");\n\n const compiler = newCompiler(logger, packageInfo, \"dist\");\n\n // group output by type:\n // - all libs\n // - all templates\n // - all software\n // - all assets\n // - all tests\n\n // Libs\n\n if (!aType || aType === \"library\") {\n for (const lib of compiler.allLibs()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(lib.fullName)}`);\n stream.write(JSON.stringify(lib) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Templates\n\n if (!aType || aType === \"template\") {\n for (const tpl of compiler.allTemplates()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(tpl.fullName)}`);\n stream.write(JSON.stringify(tpl) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"template\") {\n logger.debug(\n `Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)} ${src.srcName}`,\n );\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Software\n\n if (!aType || aType === \"software\") {\n for (const sw of compiler.allSoftware()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(sw.fullName)}`);\n stream.write(JSON.stringify(sw) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"software\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Assets\n\n if (!aType || aType === \"asset\") {\n for (const asset of compiler.allAssets()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(asset.fullName)}`);\n stream.write(JSON.stringify(asset) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"asset\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Tests\n\n if (!aType || aType === \"test\") {\n for (const src of sources) {\n if (src.fullName.type === \"test\") {\n logger.debug(\n `Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)} ${src.srcName}`,\n );\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n}\n\nexport function dumpLibs(\n logger: winston.Logger,\n stream: NodeJS.WritableStream,\n recursive: boolean,\n): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n\n const sources = parseSources(logger, packageInfo, \"dist\", \"src\", \"\");\n\n if (!recursive) {\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n\n return;\n }\n\n const compiler = newCompiler(logger, packageInfo, \"dist\");\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n compiler.addLib(src);\n }\n }\n\n for (const lib of compiler.allLibs()) {\n stream.write(JSON.stringify(lib) + \"\\n\");\n }\n}\n\nexport function dumpSoftware(logger: winston.Logger, stream: NodeJS.WritableStream): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n const compiled = compile(logger, packageInfo, \"dist\");\n\n const hashes = new Set<string>();\n const sourceMap = new Map<string, string>();\n for (const tpl of compiled.templates) {\n Object.entries(tpl.data.hashToSource).forEach(([hash, src]) => sourceMap.set(hash, src));\n getTemplateSoftware(tpl.data.template).forEach((hash) => hashes.add(hash));\n }\n\n for (const hash of hashes) {\n const src = sourceMap.get(hash);\n if (src) {\n if (Object.hasOwn(JSON.parse(src) as object, \"asset\")) {\n // Skip assets. They are kept in templates software because of backward compatibility with backend.\n continue;\n }\n stream.write(src);\n if (!src.endsWith(\"\\n\")) {\n stream.write(\"\\n\");\n }\n } else {\n throw new Error(`Source not found for hash: ${hash}`);\n }\n }\n}\n\nfunction getTemplateSoftware(tpl: TemplateDataV3): Set<string> {\n const hashes = new Set<string>();\n for (const sw of Object.values(tpl.software)) {\n hashes.add(sw.sourceHash);\n }\n for (const subTpl of Object.values(tpl.templates)) {\n getTemplateSoftware(subTpl).forEach((hash) => hashes.add(hash));\n }\n\n return new Set(hashes);\n}\n"],"mappings":";;;AAMA,SAAgB,cACd,QACA,QACA,OACM;CACN,MAAM,cAAc,eAAe,QAAQ,KAAK,EAAE,OAAO;CAEzD,MAAM,UAAU,aAAa,QAAQ,aAAa,QAAQ,OAAO,GAAG;CAEpE,MAAM,WAAW,YAAY,QAAQ,aAAa,OAAO;AAWzD,KAAI,CAAC,SAAS,UAAU,WAAW;AACjC,OAAK,MAAM,OAAO,SAAS,SAAS,EAAE;AACpC,UAAO,MAAM,yBAAyB,0BAA0B,IAAI,SAAS,GAAG;AAChF,UAAO,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK;;AAG1C,OAAK,MAAM,OAAO,QAChB,KAAI,IAAI,SAAS,SAAS,WAAW;AACnC,UAAO,MAAM,yBAAyB,0BAA0B,IAAI,SAAS,GAAG;AAChF,UAAO,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK;;;AAO9C,KAAI,CAAC,SAAS,UAAU,YAAY;AAClC,OAAK,MAAM,OAAO,SAAS,cAAc,EAAE;AACzC,UAAO,MAAM,yBAAyB,0BAA0B,IAAI,SAAS,GAAG;AAChF,UAAO,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK;;AAG1C,OAAK,MAAM,OAAO,QAChB,KAAI,IAAI,SAAS,SAAS,YAAY;AACpC,UAAO,MACL,yBAAyB,0BAA0B,IAAI,SAAS,CAAC,GAAG,IAAI,UACzE;AACD,UAAO,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK;;;AAO9C,KAAI,CAAC,SAAS,UAAU,YAAY;AAClC,OAAK,MAAM,MAAM,SAAS,aAAa,EAAE;AACvC,UAAO,MAAM,yBAAyB,0BAA0B,GAAG,SAAS,GAAG;AAC/E,UAAO,MAAM,KAAK,UAAU,GAAG,GAAG,KAAK;;AAGzC,OAAK,MAAM,OAAO,QAChB,KAAI,IAAI,SAAS,SAAS,YAAY;AACpC,UAAO,MAAM,yBAAyB,0BAA0B,IAAI,SAAS,GAAG;AAChF,UAAO,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK;;;AAO9C,KAAI,CAAC,SAAS,UAAU,SAAS;AAC/B,OAAK,MAAM,SAAS,SAAS,WAAW,EAAE;AACxC,UAAO,MAAM,yBAAyB,0BAA0B,MAAM,SAAS,GAAG;AAClF,UAAO,MAAM,KAAK,UAAU,MAAM,GAAG,KAAK;;AAG5C,OAAK,MAAM,OAAO,QAChB,KAAI,IAAI,SAAS,SAAS,SAAS;AACjC,UAAO,MAAM,yBAAyB,0BAA0B,IAAI,SAAS,GAAG;AAChF,UAAO,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK;;;AAO9C,KAAI,CAAC,SAAS,UAAU;OACjB,MAAM,OAAO,QAChB,KAAI,IAAI,SAAS,SAAS,QAAQ;AAChC,UAAO,MACL,yBAAyB,0BAA0B,IAAI,SAAS,CAAC,GAAG,IAAI,UACzE;AACD,UAAO,MAAM,KAAK,UAAU,IAAI,GAAG,KAAK;;;;AAqChD,SAAgB,aAAa,QAAwB,QAAqC;CAExF,MAAM,WAAW,QAAQ,QADL,eAAe,QAAQ,KAAK,EAAE,OAAO,EACX,OAAO;CAErD,MAAM,yBAAS,IAAI,KAAa;CAChC,MAAM,4BAAY,IAAI,KAAqB;AAC3C,MAAK,MAAM,OAAO,SAAS,WAAW;AACpC,SAAO,QAAQ,IAAI,KAAK,aAAa,CAAC,SAAS,CAAC,MAAM,SAAS,UAAU,IAAI,MAAM,IAAI,CAAC;AACxF,sBAAoB,IAAI,KAAK,SAAS,CAAC,SAAS,SAAS,OAAO,IAAI,KAAK,CAAC;;AAG5E,MAAK,MAAM,QAAQ,QAAQ;EACzB,MAAM,MAAM,UAAU,IAAI,KAAK;AAC/B,MAAI,KAAK;AACP,OAAI,OAAO,OAAO,KAAK,MAAM,IAAI,EAAY,QAAQ,CAEnD;AAEF,UAAO,MAAM,IAAI;AACjB,OAAI,CAAC,IAAI,SAAS,KAAK,CACrB,QAAO,MAAM,KAAK;QAGpB,OAAM,IAAI,MAAM,8BAA8B,OAAO;;;AAK3D,SAAS,oBAAoB,KAAkC;CAC7D,MAAM,yBAAS,IAAI,KAAa;AAChC,MAAK,MAAM,MAAM,OAAO,OAAO,IAAI,SAAS,CAC1C,QAAO,IAAI,GAAG,WAAW;AAE3B,MAAK,MAAM,UAAU,OAAO,OAAO,IAAI,UAAU,CAC/C,qBAAoB,OAAO,CAAC,SAAS,SAAS,OAAO,IAAI,KAAK,CAAC;AAGjE,QAAO,IAAI,IAAI,OAAO"}
1
+ {"version":3,"file":"dump.js","names":[],"sources":["../../src/shared/dump.ts"],"sourcesContent":["import type winston from \"winston\";\nimport { getPackageInfo, newCompiler, compile, parseSources } from \"../compiler/main\";\nimport type { ArtifactType } from \"../compiler/package\";\nimport { typedArtifactNameToString } from \"../compiler/package\";\nimport type { TemplateDataV3 } from \"@milaboratories/pl-model-backend\";\n\nexport function dumpArtifacts(\n logger: winston.Logger,\n stream: NodeJS.WritableStream,\n aType?: ArtifactType,\n): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n\n const sources = parseSources(logger, packageInfo, \"dist\", \"src\", \"\");\n\n const compiler = newCompiler(logger, packageInfo, \"dist\");\n\n // group output by type:\n // - all libs\n // - all templates\n // - all software\n // - all assets\n // - all tests\n\n // Libs\n\n if (!aType || aType === \"library\") {\n for (const lib of compiler.allLibs()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(lib.fullName)}`);\n stream.write(JSON.stringify(lib) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Templates\n\n if (!aType || aType === \"template\") {\n for (const tpl of compiler.allTemplates()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(tpl.fullName)}`);\n stream.write(JSON.stringify(tpl) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"template\") {\n logger.debug(\n `Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)} ${src.srcName}`,\n );\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Software\n\n if (!aType || aType === \"software\") {\n for (const sw of compiler.allSoftware()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(sw.fullName)}`);\n stream.write(JSON.stringify(sw) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"software\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Assets\n\n if (!aType || aType === \"asset\") {\n for (const asset of compiler.allAssets()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(asset.fullName)}`);\n stream.write(JSON.stringify(asset) + \"\\n\");\n }\n\n for (const src of sources) {\n if (src.fullName.type === \"asset\") {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)}`);\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n\n // Wasm\n\n if (!aType || aType === \"wasm\") {\n for (const wasm of compiler.allWasm()) {\n logger.debug(`Dumping to pl-tester: ${typedArtifactNameToString(wasm.fullName)}`);\n stream.write(JSON.stringify(wasm) + \"\\n\");\n }\n }\n\n // Tests\n\n if (!aType || aType === \"test\") {\n for (const src of sources) {\n if (src.fullName.type === \"test\") {\n logger.debug(\n `Dumping to pl-tester: ${typedArtifactNameToString(src.fullName)} ${src.srcName}`,\n );\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n }\n}\n\nexport function dumpLibs(\n logger: winston.Logger,\n stream: NodeJS.WritableStream,\n recursive: boolean,\n): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n\n const sources = parseSources(logger, packageInfo, \"dist\", \"src\", \"\");\n\n if (!recursive) {\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n stream.write(JSON.stringify(src) + \"\\n\");\n }\n }\n\n return;\n }\n\n const compiler = newCompiler(logger, packageInfo, \"dist\");\n for (const src of sources) {\n if (src.fullName.type === \"library\") {\n compiler.addLib(src);\n }\n }\n\n for (const lib of compiler.allLibs()) {\n stream.write(JSON.stringify(lib) + \"\\n\");\n }\n}\n\nexport function dumpSoftware(logger: winston.Logger, stream: NodeJS.WritableStream): void {\n const packageInfo = getPackageInfo(process.cwd(), logger);\n const compiled = compile(logger, packageInfo, \"dist\");\n\n const hashes = new Set<string>();\n const sourceMap = new Map<string, string>();\n for (const tpl of compiled.templates) {\n Object.entries(tpl.data.hashToSource).forEach(([hash, src]) => sourceMap.set(hash, src));\n getTemplateSoftware(tpl.data.template).forEach((hash) => hashes.add(hash));\n }\n\n for (const hash of hashes) {\n const src = sourceMap.get(hash);\n if (src) {\n if (Object.hasOwn(JSON.parse(src) as object, \"asset\")) {\n // Skip assets. They are kept in templates software because of backward compatibility with backend.\n continue;\n }\n stream.write(src);\n if (!src.endsWith(\"\\n\")) {\n stream.write(\"\\n\");\n }\n } else {\n throw new Error(`Source not found for hash: ${hash}`);\n }\n }\n}\n\nfunction getTemplateSoftware(tpl: TemplateDataV3): Set<string> {\n const hashes = new Set<string>();\n for (const sw of Object.values(tpl.software)) {\n hashes.add(sw.sourceHash);\n }\n for (const subTpl of Object.values(tpl.templates)) {\n getTemplateSoftware(subTpl).forEach((hash) => hashes.add(hash));\n }\n\n return new Set(hashes);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platforma-sdk/tengo-builder",
3
- "version": "2.5.29",
3
+ "version": "3.0.0",
4
4
  "description": "Pl Tengo Template Builder",
5
5
  "license": "UNLICENSED",
6
6
  "bin": {
@@ -16,7 +16,7 @@
16
16
  "@milaboratories/tengo-tester": "^1.6.4",
17
17
  "@oclif/core": "^4.0.37",
18
18
  "winston": "^3.17.0",
19
- "@milaboratories/pl-model-backend": "1.2.29",
19
+ "@milaboratories/pl-model-backend": "1.3.0",
20
20
  "@milaboratories/resolve-helper": "1.1.3",
21
21
  "@milaboratories/ts-helpers": "1.8.2"
22
22
  },
@@ -25,10 +25,10 @@
25
25
  "@vitest/coverage-istanbul": "^4.1.3",
26
26
  "typescript": "~5.9.3",
27
27
  "vitest": "^4.1.3",
28
- "@milaboratories/oclif-index": "1.1.1",
29
28
  "@milaboratories/build-configs": "2.0.0",
30
- "@milaboratories/ts-builder": "1.4.0",
31
- "@milaboratories/ts-configs": "1.2.3"
29
+ "@milaboratories/ts-builder": "1.5.0",
30
+ "@milaboratories/ts-configs": "1.2.3",
31
+ "@milaboratories/oclif-index": "1.1.1"
32
32
  },
33
33
  "oclif": {
34
34
  "bin": "pl-tengo",
@@ -333,3 +333,94 @@ describe("TengoTemplateCompiler.compileAndAdd", () => {
333
333
  expect(() => compiler.compileAndAdd(sources)).toThrow(/Unsatisfied dependencies/);
334
334
  });
335
335
  });
336
+
337
+ describe("TengoTemplateCompiler requiredCapabilities propagation", () => {
338
+ const wasmName: FullArtifactName = {
339
+ type: "wasm",
340
+ pkg: "@test/pkg",
341
+ id: "main",
342
+ version: "1.0.0",
343
+ };
344
+ const wasmSrc = new ArtifactSource(
345
+ "dist",
346
+ wasmName,
347
+ "wasm-hash",
348
+ "wasm-bytes-base64",
349
+ "wasm-file",
350
+ [],
351
+ [],
352
+ );
353
+
354
+ it("adds wasm:v1 when a template directly embeds a wasm artifact", () => {
355
+ const compiler = new TengoTemplateCompiler("dist");
356
+ compiler.addWasm(wasmSrc);
357
+
358
+ const tplName: FullArtifactName = {
359
+ type: "template",
360
+ pkg: "@test/pkg",
361
+ id: "tpl",
362
+ version: "1.0.0",
363
+ };
364
+ const result = compiler.compileAndAdd([
365
+ new ArtifactSource("dist", tplName, "tpl-hash", "tpl-src", "tpl-file", [wasmName], []),
366
+ ]);
367
+
368
+ expect(result.templates[0].data.template.requiredCapabilities).toEqual(["wasm:v1"]);
369
+ });
370
+
371
+ it("unions child template requiredCapabilities into the parent", () => {
372
+ const compiler = new TengoTemplateCompiler("dist");
373
+ compiler.addWasm(wasmSrc);
374
+
375
+ const childName: FullArtifactName = {
376
+ type: "template",
377
+ pkg: "@test/pkg",
378
+ id: "child",
379
+ version: "1.0.0",
380
+ };
381
+ const parentName: FullArtifactName = {
382
+ type: "template",
383
+ pkg: "@test/pkg",
384
+ id: "parent",
385
+ version: "1.0.0",
386
+ };
387
+ const childSrc = new ArtifactSource(
388
+ "dist",
389
+ childName,
390
+ "child-hash",
391
+ "child-src",
392
+ "child-file",
393
+ [wasmName],
394
+ [],
395
+ );
396
+ const parentSrc = new ArtifactSource(
397
+ "dist",
398
+ parentName,
399
+ "parent-hash",
400
+ "parent-src",
401
+ "parent-file",
402
+ [childName],
403
+ [],
404
+ );
405
+
406
+ const result = compiler.compileAndAdd([childSrc, parentSrc]);
407
+ const parent = result.templates.find((t) => t.fullName.id === "parent")!;
408
+ expect(parent.data.template.requiredCapabilities).toEqual(["wasm:v1"]);
409
+ });
410
+
411
+ it("leaves requiredCapabilities undefined when no capability is needed", () => {
412
+ const compiler = new TengoTemplateCompiler("dist");
413
+
414
+ const tplName: FullArtifactName = {
415
+ type: "template",
416
+ pkg: "@test/pkg",
417
+ id: "plain",
418
+ version: "1.0.0",
419
+ };
420
+ const result = compiler.compileAndAdd([
421
+ new ArtifactSource("dist", tplName, "plain-hash", "plain-src", "plain-file", [], []),
422
+ ]);
423
+
424
+ expect(result.templates[0].data.template.requiredCapabilities).toBeUndefined();
425
+ });
426
+ });
@@ -13,7 +13,18 @@ import {
13
13
  import { ArtifactStore } from "./artifactset";
14
14
  import { assertNever } from "./util";
15
15
  import { applyLibraryCompilerOptions, applyTemplateCompilerOptions } from "./compileroptions";
16
- import type { CompiledTemplateV3 } from "@milaboratories/pl-model-backend";
16
+ import type { CompiledTemplateV3, TemplateDataV3 } from "@milaboratories/pl-model-backend";
17
+ import { CapabilityWasm } from "@milaboratories/pl-model-backend";
18
+
19
+ /** Add a capability token to a template's `requiredCapabilities` list,
20
+ * skipping duplicates. Initializes the array lazily so the field stays
21
+ * absent for templates that need nothing. */
22
+ function addRequiredCapability(template: TemplateDataV3, capability: string): void {
23
+ template.requiredCapabilities = template.requiredCapabilities ?? [];
24
+ if (!template.requiredCapabilities.includes(capability)) {
25
+ template.requiredCapabilities.push(capability);
26
+ }
27
+ }
17
28
 
18
29
  /** A compilation result. */
19
30
  export interface TemplatesAndLibs {
@@ -21,12 +32,14 @@ export interface TemplatesAndLibs {
21
32
  libs: ArtifactSource[];
22
33
  software: ArtifactSource[];
23
34
  assets: ArtifactSource[];
35
+ wasm: ArtifactSource[];
24
36
  }
25
37
 
26
38
  export class TengoTemplateCompiler {
27
39
  private readonly libs = new ArtifactStore<ArtifactSource>((src) => src.fullName);
28
40
  private readonly software = new ArtifactStore<ArtifactSource>((src) => src.fullName);
29
41
  private readonly assets = new ArtifactStore<ArtifactSource>((src) => src.fullName);
42
+ private readonly wasm = new ArtifactStore<ArtifactSource>((src) => src.fullName);
30
43
  private readonly templates = new ArtifactStore<TemplateWithSource>((tpl) => tpl.fullName);
31
44
 
32
45
  constructor(private readonly compileMode: CompileMode) {}
@@ -89,6 +102,20 @@ export class TengoTemplateCompiler {
89
102
  data.hashToSource[asset.sourceHash] = asset.src;
90
103
  break;
91
104
  }
105
+ case "wasm": {
106
+ const wasm = this.getWasmOrError(dep);
107
+ data.template.wasm = data.template.wasm ?? {};
108
+ data.template.wasm[artifactNameToString(dep)] = {
109
+ ...formatArtefactNameAndVersion(wasm.fullName),
110
+ sourceHash: wasm.sourceHash,
111
+ };
112
+ data.hashToSource[wasm.sourceHash] = wasm.src;
113
+ // Embedding a wasm artifact means this template requires the
114
+ // backend's wasm runtime to run. The token is propagated upward
115
+ // when this template is in turn embedded as a sub-template.
116
+ addRequiredCapability(data.template, CapabilityWasm);
117
+ break;
118
+ }
92
119
  case "template": {
93
120
  if (typedArtifactNamesEquals(fullName, dep))
94
121
  // skipping self reference
@@ -103,6 +130,13 @@ export class TengoTemplateCompiler {
103
130
  data.hashToSource[hash] = src;
104
131
  }
105
132
 
133
+ // Union the sub-template's compile-time-computed capability
134
+ // requirements into ours, so the top template carries the full
135
+ // transitive set without consumers having to walk the tree.
136
+ for (const cap of tpl.data.template.requiredCapabilities ?? []) {
137
+ addRequiredCapability(data.template, cap);
138
+ }
139
+
106
140
  break;
107
141
  }
108
142
  case "test":
@@ -234,6 +268,31 @@ export class TengoTemplateCompiler {
234
268
  return asset;
235
269
  }
236
270
 
271
+ addWasm(wasm: ArtifactSource) {
272
+ const wasmFromMap = this.wasm.add(wasm.compileMode, wasm, false);
273
+ if (wasmFromMap && !fullNameEquals(wasm.fullName, wasmFromMap.fullName))
274
+ throw new Error(
275
+ `compiler already contain info for wasm: adding = ${fullNameToString(wasm.fullName)}, contains = ${fullNameToString(wasmFromMap.fullName)}`,
276
+ );
277
+ }
278
+
279
+ allWasm(): ArtifactSource[] {
280
+ return this.wasm.array(this.compileMode);
281
+ }
282
+
283
+ getWasm(name: TypedArtifactName): ArtifactSource | undefined {
284
+ if (name.type !== "wasm")
285
+ throw new Error(`illegal artifact type: got ${name.type} instead of 'wasm'`);
286
+
287
+ return this.wasm.get(this.compileMode, name);
288
+ }
289
+
290
+ getWasmOrError(name: TypedArtifactName): ArtifactSource {
291
+ const wasm = this.getWasm(name);
292
+ if (!wasm) throw new Error(`wasm info not found: ${artifactNameToString(name)}`);
293
+ return wasm;
294
+ }
295
+
237
296
  addTemplate(tpl: TemplateWithSource) {
238
297
  const tplFromMap = this.templates.add(tpl.compileMode, tpl, false);
239
298
  if (tplFromMap && !fullNameEquals(tpl.fullName, tplFromMap.fullName))
@@ -268,6 +327,8 @@ export class TengoTemplateCompiler {
268
327
  return this.getSoftware(name);
269
328
  case "asset":
270
329
  return this.getAsset(name);
330
+ case "wasm":
331
+ return this.getWasm(name);
271
332
  case "test":
272
333
  // Tests are ignored by the complier. They should never be compiled into templates or libs and
273
334
  // should never be a dependency.
@@ -283,6 +344,7 @@ export class TengoTemplateCompiler {
283
344
  libs: [],
284
345
  software: [],
285
346
  assets: [],
347
+ wasm: [],
286
348
  };
287
349
 
288
350
  let current: ArtifactSource[] = [];
@@ -300,6 +362,10 @@ export class TengoTemplateCompiler {
300
362
  // add assets 'as-is' to be able to resolve them as dependencies
301
363
  this.addAsset(src);
302
364
  result.assets.push(src);
365
+ } else if (src.fullName.type === "wasm") {
366
+ // add wasm 'as-is' to be able to resolve them as dependencies
367
+ this.addWasm(src);
368
+ result.wasm.push(src);
303
369
  } else {
304
370
  current.push(src);
305
371
  }
@@ -349,6 +415,11 @@ export class TengoTemplateCompiler {
349
415
  this.addAsset(src);
350
416
  result.assets.push(src);
351
417
  break;
418
+ case "wasm":
419
+ // wasm dependencies are added as is
420
+ this.addWasm(src);
421
+ result.wasm.push(src);
422
+ break;
352
423
  case "template":
353
424
  // templates are compiled and then added
354
425
  try {