@powerhousedao/codegen 6.0.0-dev.190 → 6.0.0-dev.192
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{templates-BbNsigQX.mjs → file-builders-BkbVW0kT.mjs} +2322 -383
- package/dist/file-builders-BkbVW0kT.mjs.map +1 -0
- package/dist/index-CEDWX5sL.d.mts +349 -0
- package/dist/index-CEDWX5sL.d.mts.map +1 -0
- package/dist/index.d.mts +42 -101
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +4492 -325
- package/dist/index.mjs.map +1 -1
- package/dist/src/file-builders/index.d.mts +2 -3
- package/dist/src/file-builders/index.mjs +2 -3
- package/dist/src/name-builders/index.d.mts +2 -2
- package/dist/src/name-builders/index.mjs +2 -146
- package/dist/src/templates/index.d.mts +34 -74
- package/dist/src/templates/index.d.mts.map +1 -1
- package/dist/src/templates/index.mjs +2 -2
- package/dist/src/utils/index.d.mts +6 -18
- package/dist/src/utils/index.d.mts.map +1 -1
- package/dist/src/utils/index.mjs +2 -380
- package/dist/{validation-Bpg_44mW.d.mts → validation-Z3z0BJlu.d.mts} +2 -2
- package/dist/{validation-Bpg_44mW.d.mts.map → validation-Z3z0BJlu.d.mts.map} +1 -1
- package/package.json +16 -9
- package/dist/file-builders-BV9wDPPZ.mjs +0 -1652
- package/dist/file-builders-BV9wDPPZ.mjs.map +0 -1
- package/dist/index-CHAnPBj2.d.mts +0 -199
- package/dist/index-CHAnPBj2.d.mts.map +0 -1
- package/dist/index-CJZGVSYg.d.mts +0 -65
- package/dist/index-CJZGVSYg.d.mts.map +0 -1
- package/dist/src/name-builders/index.mjs.map +0 -1
- package/dist/src/utils/index.mjs.map +0 -1
- package/dist/templates-BbNsigQX.mjs.map +0 -1
- package/dist/types-e2ztuDtG.d.mts +0 -87
- package/dist/types-e2ztuDtG.d.mts.map +0 -1
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DocumentModelGlobalStateSchema, ManifestSchema } from "@powerhousedao/shared/document-model";
|
|
2
2
|
import { camelCase, capitalCase, constantCase, kebabCase, pascalCase } from "change-case";
|
|
3
|
+
import path, { join } from "path";
|
|
4
|
+
import { capitalize, concat, filter, find, flatMap, forEach, fromEntries, isIncludedIn, isNonNullish, isString, isTruthy, last, map, merge, pipe, prop, sort, subtract, unique, uniqueBy, when } from "remeda";
|
|
5
|
+
import { IndentationText, Project, SyntaxKind, VariableDeclarationKind, ts } from "ts-morph";
|
|
6
|
+
import arg from "arg";
|
|
7
|
+
import { readdirSync, statSync } from "fs";
|
|
8
|
+
import { loadJsonFile, loadJsonFileSync } from "load-json-file";
|
|
9
|
+
import { VERSIONED_DEPENDENCIES, VERSIONED_DEV_DEPENDENCIES, directoryExists, fileExists, makeVersionedDependencies, spawnAsync, writeFileEnsuringDir } from "@powerhousedao/shared/clis";
|
|
10
|
+
import { format } from "prettier";
|
|
11
|
+
import fs, { copyFile, mkdir, readdir, writeFile } from "node:fs/promises";
|
|
12
|
+
import { stripVTControlCharacters } from "node:util";
|
|
13
|
+
import path$1, { join as join$1, relative } from "node:path";
|
|
14
|
+
import { generate } from "@graphql-codegen/cli";
|
|
15
|
+
import { generatorTypeDefs, validationSchema } from "@powerhousedao/document-engineering/graphql";
|
|
16
|
+
import { writeJsonFile } from "write-json-file";
|
|
3
17
|
function isEOL(c) {
|
|
4
18
|
return c === 10 || c === 13;
|
|
5
19
|
}
|
|
@@ -302,7 +316,7 @@ const int = {
|
|
|
302
316
|
};
|
|
303
317
|
//#endregion
|
|
304
318
|
//#region ../../node_modules/.pnpm/@jsr+std__yaml@1.0.12/node_modules/@jsr/std__yaml/_type/map.js
|
|
305
|
-
const map = {
|
|
319
|
+
const map$1 = {
|
|
306
320
|
tag: "tag:yaml.org,2002:map",
|
|
307
321
|
resolve() {
|
|
308
322
|
return true;
|
|
@@ -314,7 +328,7 @@ const map = {
|
|
|
314
328
|
};
|
|
315
329
|
//#endregion
|
|
316
330
|
//#region ../../node_modules/.pnpm/@jsr+std__yaml@1.0.12/node_modules/@jsr/std__yaml/_type/merge.js
|
|
317
|
-
const merge = {
|
|
331
|
+
const merge$1 = {
|
|
318
332
|
tag: "tag:yaml.org,2002:merge",
|
|
319
333
|
kind: "scalar",
|
|
320
334
|
resolve: (data) => data === "<<" || data === null,
|
|
@@ -525,7 +539,7 @@ function createSchema({ explicitTypes = [], implicitTypes = [], include }) {
|
|
|
525
539
|
*/ const FAILSAFE_SCHEMA = createSchema({ explicitTypes: [
|
|
526
540
|
str,
|
|
527
541
|
seq,
|
|
528
|
-
map
|
|
542
|
+
map$1
|
|
529
543
|
] });
|
|
530
544
|
/**
|
|
531
545
|
* Standard YAML's JSON schema.
|
|
@@ -554,7 +568,7 @@ function createSchema({ explicitTypes = [], implicitTypes = [], include }) {
|
|
|
554
568
|
pairs,
|
|
555
569
|
set
|
|
556
570
|
],
|
|
557
|
-
implicitTypes: [timestamp, merge],
|
|
571
|
+
implicitTypes: [timestamp, merge$1],
|
|
558
572
|
include: CORE_SCHEMA
|
|
559
573
|
});
|
|
560
574
|
/***
|
|
@@ -1720,7 +1734,7 @@ var TemplateClass = class TemplateClass extends String {
|
|
|
1720
1734
|
const html = tag("html");
|
|
1721
1735
|
const css = tag("css");
|
|
1722
1736
|
const js = tag("js");
|
|
1723
|
-
const ts = tag("ts");
|
|
1737
|
+
const ts$1 = tag("ts");
|
|
1724
1738
|
tag("jsx");
|
|
1725
1739
|
const tsx = tag("tsx");
|
|
1726
1740
|
const json = tag("json", JSON.parse);
|
|
@@ -2079,10 +2093,9 @@ export function NavigationBreadcrumbs() {
|
|
|
2079
2093
|
`.raw;
|
|
2080
2094
|
//#endregion
|
|
2081
2095
|
//#region src/templates/app/config.ts
|
|
2082
|
-
const appConfigFileTemplate = (v) => ts`
|
|
2096
|
+
const appConfigFileTemplate = (v) => ts$1`
|
|
2083
2097
|
import type { PHAppConfig } from "@powerhousedao/reactor-browser";
|
|
2084
2098
|
|
|
2085
|
-
/** Editor config for the <%= pascalCaseAppName %> */
|
|
2086
2099
|
export const editorConfig: PHAppConfig = {
|
|
2087
2100
|
isDragAndDropEnabled: ${v.isDragAndDropEnabledString},
|
|
2088
2101
|
allowedDocumentTypes: ${v.allowedDocumentTypesString}
|
|
@@ -2091,6 +2104,10 @@ export const editorConfig: PHAppConfig = {
|
|
|
2091
2104
|
//#endregion
|
|
2092
2105
|
//#region src/templates/app/editor.ts
|
|
2093
2106
|
const appEditorFileTemplate = () => tsx`
|
|
2107
|
+
/**
|
|
2108
|
+
* WARNING: DO NOT EDIT
|
|
2109
|
+
* This file is auto-generated and updated by codegen
|
|
2110
|
+
*/
|
|
2094
2111
|
import { useSetPHAppConfig } from "@powerhousedao/reactor-browser";
|
|
2095
2112
|
import type { EditorProps } from "document-model";
|
|
2096
2113
|
import { DriveExplorer } from "./components/DriveExplorer.js";
|
|
@@ -2941,24 +2958,53 @@ exec ph switchboard --port \${PORT:-3000}
|
|
|
2941
2958
|
`;
|
|
2942
2959
|
//#endregion
|
|
2943
2960
|
//#region src/templates/boilerplate/document-models/document-models.ts
|
|
2944
|
-
const documentModelsTemplate = ts`
|
|
2961
|
+
const documentModelsTemplate = ts$1`
|
|
2962
|
+
/**
|
|
2963
|
+
* WARNING: DO NOT EDIT
|
|
2964
|
+
* This file is auto-generated and updated by codegen
|
|
2965
|
+
*/
|
|
2945
2966
|
import type { DocumentModelModule } from "document-model";
|
|
2946
2967
|
|
|
2947
|
-
export const documentModels: DocumentModelModule[] = [];
|
|
2968
|
+
export const documentModels: DocumentModelModule<any>[] = [];
|
|
2948
2969
|
`.raw;
|
|
2949
2970
|
//#endregion
|
|
2950
2971
|
//#region src/templates/boilerplate/document-models/index.ts
|
|
2951
|
-
const documentModelsIndexTemplate =
|
|
2972
|
+
const documentModelsIndexTemplate = `
|
|
2973
|
+
/**
|
|
2974
|
+
* WARNING: DO NOT EDIT
|
|
2975
|
+
* This file is auto-generated and updated by codegen
|
|
2976
|
+
*/
|
|
2977
|
+
`;
|
|
2978
|
+
//#endregion
|
|
2979
|
+
//#region src/templates/boilerplate/document-models/upgrade-manifests.ts
|
|
2980
|
+
const upgradeManifestsTemplate = ts$1`
|
|
2981
|
+
/**
|
|
2982
|
+
* WARNING: DO NOT EDIT
|
|
2983
|
+
* This file is auto-generated and updated by codegen
|
|
2984
|
+
*/
|
|
2985
|
+
import type { UpgradeManifest } from "document-model";
|
|
2986
|
+
|
|
2987
|
+
export const upgradeManifests: UpgradeManifest<readonly number[]>[] = [];
|
|
2988
|
+
`.raw;
|
|
2952
2989
|
//#endregion
|
|
2953
2990
|
//#region src/templates/boilerplate/editors/editors.ts
|
|
2954
|
-
const editorsTemplate = ts`
|
|
2991
|
+
const editorsTemplate = ts$1`
|
|
2992
|
+
/**
|
|
2993
|
+
* WARNING: DO NOT EDIT
|
|
2994
|
+
* This file is auto-generated and updated by codegen
|
|
2995
|
+
*/
|
|
2955
2996
|
import type { EditorModule } from "document-model";
|
|
2956
2997
|
|
|
2957
2998
|
export const editors: EditorModule[] = [];
|
|
2958
2999
|
`.raw;
|
|
2959
3000
|
//#endregion
|
|
2960
3001
|
//#region src/templates/boilerplate/editors/index.ts
|
|
2961
|
-
const editorsIndexTemplate =
|
|
3002
|
+
const editorsIndexTemplate = `
|
|
3003
|
+
/**
|
|
3004
|
+
* WARNING: DO NOT EDIT
|
|
3005
|
+
* This file is auto-generated and updated by codegen
|
|
3006
|
+
*/
|
|
3007
|
+
`;
|
|
2962
3008
|
//#endregion
|
|
2963
3009
|
//#region src/templates/boilerplate/eslint.config.js.ts
|
|
2964
3010
|
const eslintConfigTemplate = js`
|
|
@@ -3507,14 +3553,18 @@ function _taggedTemplateLiteral(e, t) {
|
|
|
3507
3553
|
//#endregion
|
|
3508
3554
|
//#region src/templates/boilerplate/index.html.ts
|
|
3509
3555
|
var _templateObject$1;
|
|
3510
|
-
const indexHtmlTemplate = html(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["<!
|
|
3556
|
+
const indexHtmlTemplate = html(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["<!doctype html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta\n name=\"description\"\n content=\"Connect is a hub for your most important documents and processes, translated into software. Easily capture data in a structured way with dedicated business process packages. Collaborate on shared documents with ease while using your preferred storage solution (decentralized, centralized, or local).\"\n />\n <title>Powerhouse Connect</title>\n <link rel=\"icon\" href=\"/icon.ico\" />\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link\n href=\"https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap\"\n rel=\"stylesheet\"\n />\n </head>\n <body>\n <div id=\"root\"></div>\n <link href=\"/style.css\" rel=\"stylesheet\" />\n <script type=\"module\" src=\"/main.tsx\"><\/script>\n </body>\n </html> "]))).raw;
|
|
3511
3557
|
//#endregion
|
|
3512
3558
|
//#region src/templates/boilerplate/index.html.legacy.ts
|
|
3513
3559
|
var _templateObject;
|
|
3514
3560
|
const legacyIndexHtmlTemplate = html(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <meta\n name=\"description\"\n content=\"Connect is a hub for your most important documents and processes, translated into software. Easily capture data in a structured way with dedicated business process packages. Collaborate on shared documents with ease while using your preferred storage solution (decentralized, centralized, or local).\"\n />\n <title>Powerhouse Connect</title>\n <link rel=\"icon\" href=\"/icon.ico\" />\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" />\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin />\n <link\n href=\"https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap\"\n rel=\"stylesheet\"\n />\n <style>\n @import \"tailwindcss\";\n @import \"@powerhousedao/design-system/style.css\";\n @import \"@powerhousedao/document-engineering/style.css\";\n @source \"./node_modules/@powerhousedao/connect\";\n </style>\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\">\n // initializes Connect on '<div id=\"root\"></div>'\n import \"@powerhousedao/connect/main.js\";\n <\/script>\n </body>\n </html>\n"]))).raw;
|
|
3515
3561
|
//#endregion
|
|
3516
3562
|
//#region src/templates/boilerplate/index.ts
|
|
3517
|
-
const indexTsTemplate = ts`
|
|
3563
|
+
const indexTsTemplate = ts$1`
|
|
3564
|
+
/**
|
|
3565
|
+
* WARNING: DO NOT EDIT
|
|
3566
|
+
* This file is auto-generated and updated by codegen
|
|
3567
|
+
*/
|
|
3518
3568
|
import type { Manifest } from "document-model";
|
|
3519
3569
|
import manifestJson from "./powerhouse.manifest.json" with { type: "json" };
|
|
3520
3570
|
export { documentModels } from "./document-models/document-models.js";
|
|
@@ -4191,6 +4241,10 @@ For more information on this, and how to apply and follow the GNU AGPL, see
|
|
|
4191
4241
|
//#endregion
|
|
4192
4242
|
//#region src/templates/boilerplate/main.tsx.ts
|
|
4193
4243
|
const mainTsxTemplate = tsx`
|
|
4244
|
+
/**
|
|
4245
|
+
* WARNING: DO NOT EDIT
|
|
4246
|
+
* This file is auto-generated and updated by codegen
|
|
4247
|
+
*/
|
|
4194
4248
|
import { startConnect } from "@powerhousedao/connect";
|
|
4195
4249
|
import * as localPackage from "./index.js";
|
|
4196
4250
|
|
|
@@ -4288,8 +4342,6 @@ const dependenciesTemplate = (versionedDependencies) => json`
|
|
|
4288
4342
|
`.raw;
|
|
4289
4343
|
const devDependenciesTemplate = (versionedDevDependencies) => json`
|
|
4290
4344
|
${versionedDevDependencies.join(",\n")},
|
|
4291
|
-
"@electric-sql/pglite": "0.3.15",
|
|
4292
|
-
"@electric-sql/pglite-tools": "0.2.20",
|
|
4293
4345
|
"@eslint/js": "^9.38.0",
|
|
4294
4346
|
"@tailwindcss/cli": "^4.1.18",
|
|
4295
4347
|
"@types/node": "^24.9.2",
|
|
@@ -4303,7 +4355,6 @@ const devDependenciesTemplate = (versionedDevDependencies) => json`
|
|
|
4303
4355
|
"tailwindcss": "^4.1.16",
|
|
4304
4356
|
"typescript": "^5.9.3",
|
|
4305
4357
|
"typescript-eslint": "^8.46.2",
|
|
4306
|
-
"vite": "8.0.2",
|
|
4307
4358
|
"vitest": "4.1.1",
|
|
4308
4359
|
"@vitejs/plugin-react": "6.0.1",
|
|
4309
4360
|
"vite-tsconfig-paths": "6.1.1"
|
|
@@ -4649,7 +4700,12 @@ const styleTemplate = css`
|
|
|
4649
4700
|
`.raw;
|
|
4650
4701
|
//#endregion
|
|
4651
4702
|
//#region src/templates/boilerplate/subgraphs/index.ts
|
|
4652
|
-
const subgraphsIndexTemplate =
|
|
4703
|
+
const subgraphsIndexTemplate = `
|
|
4704
|
+
/**
|
|
4705
|
+
* WARNING: DO NOT EDIT
|
|
4706
|
+
* This file is auto-generated and updated by codegen
|
|
4707
|
+
*/
|
|
4708
|
+
`;
|
|
4653
4709
|
//#endregion
|
|
4654
4710
|
//#region src/templates/boilerplate/tsconfig.json.ts
|
|
4655
4711
|
const tsconfigPathsTemplate = json`
|
|
@@ -4703,29 +4759,8 @@ const tsConfigTemplate = json`
|
|
|
4703
4759
|
}
|
|
4704
4760
|
`.raw;
|
|
4705
4761
|
//#endregion
|
|
4706
|
-
//#region src/templates/boilerplate/vite.config.ts.ts
|
|
4707
|
-
const viteConfigTemplate = ts`
|
|
4708
|
-
import { getConnectBaseViteConfig } from "@powerhousedao/builder-tools";
|
|
4709
|
-
import { defineConfig, mergeConfig, type UserConfig } from "vite";
|
|
4710
|
-
|
|
4711
|
-
export default defineConfig(({ mode }) => {
|
|
4712
|
-
const baseConnectViteConfig = getConnectBaseViteConfig({
|
|
4713
|
-
mode,
|
|
4714
|
-
dirname: import.meta.dirname,
|
|
4715
|
-
});
|
|
4716
|
-
|
|
4717
|
-
const additionalViteConfig: UserConfig = {
|
|
4718
|
-
// add your own vite config here
|
|
4719
|
-
};
|
|
4720
|
-
|
|
4721
|
-
const config = mergeConfig(baseConnectViteConfig, additionalViteConfig);
|
|
4722
|
-
|
|
4723
|
-
return config;
|
|
4724
|
-
});
|
|
4725
|
-
`;
|
|
4726
|
-
//#endregion
|
|
4727
4762
|
//#region src/templates/boilerplate/vitest.config.ts.ts
|
|
4728
|
-
const vitestConfigTemplate = ts`
|
|
4763
|
+
const vitestConfigTemplate = ts$1`
|
|
4729
4764
|
import { defineConfig } from "vitest/config";
|
|
4730
4765
|
import react from "@vitejs/plugin-react";
|
|
4731
4766
|
import tsconfigPaths from "vite-tsconfig-paths";
|
|
@@ -4892,6 +4927,10 @@ export default function Editor() {
|
|
|
4892
4927
|
//#endregion
|
|
4893
4928
|
//#region src/templates/document-editor/module.ts
|
|
4894
4929
|
const documentEditorModuleFileTemplate = (v) => tsx`
|
|
4930
|
+
/**
|
|
4931
|
+
* WARNING: DO NOT EDIT
|
|
4932
|
+
* This file is auto-generated and updated by codegen
|
|
4933
|
+
*/
|
|
4895
4934
|
import type { EditorModule } from "document-model";
|
|
4896
4935
|
import { lazy } from "react";
|
|
4897
4936
|
|
|
@@ -4921,12 +4960,16 @@ function buildModuleActionsSpreadExport(modules, camelCaseDocumentType) {
|
|
|
4921
4960
|
return `
|
|
4922
4961
|
export const actions = { ...baseActions, ${buildModuleActionsNames(modules, camelCaseDocumentType).map((n) => `...${n}`).join(",\n")} }`;
|
|
4923
4962
|
}
|
|
4924
|
-
const documentModelRootActionsFileTemplate = (v) => ts`
|
|
4963
|
+
const documentModelRootActionsFileTemplate = (v) => ts$1`
|
|
4964
|
+
/**
|
|
4965
|
+
* WARNING: DO NOT EDIT
|
|
4966
|
+
* This file is auto-generated and updated by codegen
|
|
4967
|
+
*/
|
|
4925
4968
|
import { baseActions } from "document-model";
|
|
4926
|
-
${buildModuleActionsImports(v.modules, v.camelCaseDocumentType)}
|
|
4969
|
+
${buildModuleActionsImports(v.specification.modules, v.camelCaseDocumentType)}
|
|
4927
4970
|
|
|
4928
4971
|
/** Actions for the ${v.pascalCaseDocumentType} document model */
|
|
4929
|
-
${buildModuleActionsSpreadExport(v.modules, v.camelCaseDocumentType)}
|
|
4972
|
+
${buildModuleActionsSpreadExport(v.specification.modules, v.camelCaseDocumentType)}
|
|
4930
4973
|
`.raw;
|
|
4931
4974
|
//#endregion
|
|
4932
4975
|
//#region src/templates/document-model/gen/actions.ts
|
|
@@ -4951,16 +4994,24 @@ function makeModuleActionTypesUnion(modules, pascalCaseDocumentType) {
|
|
|
4951
4994
|
function makeDocumentActionType(modules, pascalCaseDocumentType) {
|
|
4952
4995
|
return `export type ${pascalCaseDocumentType}Action = ${makeModuleActionTypesUnion(modules, pascalCaseDocumentType)};`;
|
|
4953
4996
|
}
|
|
4954
|
-
const documentModelGenActionsFileTemplate = (v) => ts`
|
|
4955
|
-
|
|
4997
|
+
const documentModelGenActionsFileTemplate = (v) => ts$1`
|
|
4998
|
+
/**
|
|
4999
|
+
* WARNING: DO NOT EDIT
|
|
5000
|
+
* This file is auto-generated and updated by codegen
|
|
5001
|
+
*/
|
|
5002
|
+
${makeModuleActionsTypeImports(v.specification.modules, v.pascalCaseDocumentType)}
|
|
4956
5003
|
|
|
4957
|
-
${makeModuleActionsTypeExports(v.modules)}
|
|
5004
|
+
${makeModuleActionsTypeExports(v.specification.modules)}
|
|
4958
5005
|
|
|
4959
|
-
${makeDocumentActionType(v.modules, v.pascalCaseDocumentType)}
|
|
5006
|
+
${makeDocumentActionType(v.specification.modules, v.pascalCaseDocumentType)}
|
|
4960
5007
|
`.raw;
|
|
4961
5008
|
//#endregion
|
|
4962
5009
|
//#region src/templates/document-model/gen/controller.ts
|
|
4963
|
-
const documentModelGenControllerFileTemplate = (v) => ts`
|
|
5010
|
+
const documentModelGenControllerFileTemplate = (v) => ts$1`
|
|
5011
|
+
/**
|
|
5012
|
+
* WARNING: DO NOT EDIT
|
|
5013
|
+
* This file is auto-generated and updated by codegen
|
|
5014
|
+
*/
|
|
4964
5015
|
import { PHDocumentController } from "document-model";
|
|
4965
5016
|
import { ${v.pascalCaseDocumentType} } from "../module.js";
|
|
4966
5017
|
import type { ${v.actionTypeName}, ${v.phStateName} } from "./types.js";
|
|
@@ -4981,12 +5032,20 @@ function buildModuleCreatorsExport(module, camelCaseDocumentType) {
|
|
|
4981
5032
|
function buildCreatorsExports(modules, camelCaseDocumentType) {
|
|
4982
5033
|
return modules.flatMap((module) => buildModuleCreatorsExport(module, camelCaseDocumentType)).join("\n");
|
|
4983
5034
|
}
|
|
4984
|
-
const documentModelGenCreatorsFileTemplate = (v) => ts`
|
|
4985
|
-
|
|
5035
|
+
const documentModelGenCreatorsFileTemplate = (v) => ts$1`
|
|
5036
|
+
/**
|
|
5037
|
+
* WARNING: DO NOT EDIT
|
|
5038
|
+
* This file is auto-generated and updated by codegen
|
|
5039
|
+
*/
|
|
5040
|
+
${buildCreatorsExports(v.specification.modules, v.camelCaseDocumentType)}
|
|
4986
5041
|
`.raw;
|
|
4987
5042
|
//#endregion
|
|
4988
5043
|
//#region src/templates/document-model/gen/document-schema.ts
|
|
4989
|
-
const documentModelDocumentSchemaFileTemplate = (v) => ts`
|
|
5044
|
+
const documentModelDocumentSchemaFileTemplate = (v) => ts$1`
|
|
5045
|
+
/**
|
|
5046
|
+
* WARNING: DO NOT EDIT
|
|
5047
|
+
* This file is auto-generated and updated by codegen
|
|
5048
|
+
*/
|
|
4990
5049
|
import {
|
|
4991
5050
|
BaseDocumentHeaderSchema,
|
|
4992
5051
|
BaseDocumentStateSchema,
|
|
@@ -5042,8 +5101,12 @@ export function ${v.assertIsPhDocumentOfTypeFunctionName}(
|
|
|
5042
5101
|
`.raw;
|
|
5043
5102
|
//#endregion
|
|
5044
5103
|
//#region src/templates/document-model/gen/document-type.ts
|
|
5045
|
-
const documentModelDocumentTypeTemplate = (v) => ts`
|
|
5046
|
-
|
|
5104
|
+
const documentModelDocumentTypeTemplate = (v) => ts$1`
|
|
5105
|
+
/**
|
|
5106
|
+
* WARNING: DO NOT EDIT
|
|
5107
|
+
* This file is auto-generated and updated by codegen
|
|
5108
|
+
*/
|
|
5109
|
+
export const ${v.documentTypeVariableName} = "${v.documentModelState.id}";
|
|
5047
5110
|
`.raw;
|
|
5048
5111
|
//#endregion
|
|
5049
5112
|
//#region src/templates/document-model/gen/index.ts
|
|
@@ -5053,7 +5116,11 @@ function buildModuleOperationsExports(module) {
|
|
|
5053
5116
|
function buildModulesOperationsExports(modules) {
|
|
5054
5117
|
return modules.map(buildModuleOperationsExports).join("\n");
|
|
5055
5118
|
}
|
|
5056
|
-
const documentModelGenIndexFileTemplate = (v) => ts`
|
|
5119
|
+
const documentModelGenIndexFileTemplate = (v) => ts$1`
|
|
5120
|
+
/**
|
|
5121
|
+
* WARNING: DO NOT EDIT
|
|
5122
|
+
* This file is auto-generated and updated by codegen
|
|
5123
|
+
*/
|
|
5057
5124
|
export * from './actions.js';
|
|
5058
5125
|
export * from './document-model.js';
|
|
5059
5126
|
export * from './types.js';
|
|
@@ -5071,113 +5138,221 @@ export * from "./controller.js";
|
|
|
5071
5138
|
export * from "./schema/index.js";
|
|
5072
5139
|
export * from "./document-type.js";
|
|
5073
5140
|
export * from "./document-schema.js";
|
|
5074
|
-
${buildModulesOperationsExports(v.modules)}
|
|
5141
|
+
${buildModulesOperationsExports(v.specification.modules)}
|
|
5075
5142
|
`.raw;
|
|
5076
5143
|
//#endregion
|
|
5144
|
+
//#region src/name-builders/get-action-names.ts
|
|
5145
|
+
function getActionTypeName(operation) {
|
|
5146
|
+
if (!operation.name) return;
|
|
5147
|
+
return `${pascalCase(operation.name)}Action`;
|
|
5148
|
+
}
|
|
5149
|
+
function getActionInputName(operation) {
|
|
5150
|
+
if (!operation.name) return;
|
|
5151
|
+
if (!operationHasInput(operation)) return;
|
|
5152
|
+
return `${pascalCase(operation.name)}Input`;
|
|
5153
|
+
}
|
|
5154
|
+
function getActionType(operation) {
|
|
5155
|
+
if (!operation.name) return;
|
|
5156
|
+
return constantCase(operation.name);
|
|
5157
|
+
}
|
|
5158
|
+
function getActionInputTypeNames(args) {
|
|
5159
|
+
return args.module.operations.map(getActionInputName).join(",\n");
|
|
5160
|
+
}
|
|
5161
|
+
//#endregion
|
|
5162
|
+
//#region src/name-builders/get-variable-names.ts
|
|
5163
|
+
function getEditorVariableNames({ documentModelDocumentTypeName }) {
|
|
5164
|
+
return {
|
|
5165
|
+
documentModelDocumentTypeName,
|
|
5166
|
+
documentVariableName: camelCase(documentModelDocumentTypeName),
|
|
5167
|
+
useSelectedDocumentHookName: `useSelected${documentModelDocumentTypeName}`,
|
|
5168
|
+
documentNameVariableName: `${documentModelDocumentTypeName}Name`,
|
|
5169
|
+
dispatchFunctionName: "dispatch",
|
|
5170
|
+
onClickEditHandlerName: `onClickEdit${documentModelDocumentTypeName}Name`,
|
|
5171
|
+
onCancelEditHandlerName: `onClickCancelEdit${documentModelDocumentTypeName}Name`,
|
|
5172
|
+
setNameActionName: "setName",
|
|
5173
|
+
isEditingVariableName: "isEditing",
|
|
5174
|
+
setIsEditingFunctionName: "setIsEditing",
|
|
5175
|
+
onSubmitSetNameFunctionName: `onSubmitSet${documentModelDocumentTypeName}Name`
|
|
5176
|
+
};
|
|
5177
|
+
}
|
|
5178
|
+
function getDocumentModelDirName(documentModelState, existingDirName) {
|
|
5179
|
+
if (existingDirName) return existingDirName;
|
|
5180
|
+
return kebabCase(documentModelState.name);
|
|
5181
|
+
}
|
|
5182
|
+
function getLatestDocumentModelSpec({ specifications }) {
|
|
5183
|
+
return specifications[specifications.length - 1];
|
|
5184
|
+
}
|
|
5185
|
+
function getDocumentModelSpecByVersionNumber({ specifications }, version) {
|
|
5186
|
+
const specificationByIndex = specifications[version];
|
|
5187
|
+
const specificationByNumber = specifications.find((spec) => spec.version === version);
|
|
5188
|
+
if (!specificationByNumber) {
|
|
5189
|
+
console.error(`Specification with version number ${version} does not exist in the document model specifications array`);
|
|
5190
|
+
return specificationByIndex;
|
|
5191
|
+
}
|
|
5192
|
+
if (specificationByIndex.version !== specificationByNumber.version) {
|
|
5193
|
+
console.error(`Specification with version ${version} does not match specifications array at index ${version}`);
|
|
5194
|
+
return specificationByIndex;
|
|
5195
|
+
}
|
|
5196
|
+
return specificationByNumber;
|
|
5197
|
+
}
|
|
5198
|
+
function getLatestDocumentModelSpecVersionNumber(documentModelState) {
|
|
5199
|
+
return getLatestDocumentModelSpec(documentModelState).version;
|
|
5200
|
+
}
|
|
5201
|
+
function getDocumentModelVariableNames(documentModelName) {
|
|
5202
|
+
const kebabCaseDocumentType = kebabCase(documentModelName);
|
|
5203
|
+
const pascalCaseDocumentType = pascalCase(documentModelName);
|
|
5204
|
+
const camelCaseDocumentType = camelCase(documentModelName);
|
|
5205
|
+
const documentTypeVariableName = `${camelCaseDocumentType}DocumentType`;
|
|
5206
|
+
const stateName = `${pascalCaseDocumentType}State`;
|
|
5207
|
+
const globalStateName = `${pascalCaseDocumentType}GlobalState`;
|
|
5208
|
+
const localStateName = `${pascalCaseDocumentType}LocalState`;
|
|
5209
|
+
const phStateName = `${pascalCaseDocumentType}PHState`;
|
|
5210
|
+
const phDocumentTypeName = `${pascalCaseDocumentType}Document`;
|
|
5211
|
+
const actionTypeName = `${pascalCaseDocumentType}Action`;
|
|
5212
|
+
const actionsTypeName = `${actionTypeName}s`;
|
|
5213
|
+
const actionsName = camelCase(actionsTypeName);
|
|
5214
|
+
return {
|
|
5215
|
+
kebabCaseDocumentType,
|
|
5216
|
+
pascalCaseDocumentType,
|
|
5217
|
+
camelCaseDocumentType,
|
|
5218
|
+
documentTypeVariableName,
|
|
5219
|
+
upgradeManifestName: `${camelCaseDocumentType}UpgradeManifest`,
|
|
5220
|
+
stateName,
|
|
5221
|
+
globalStateName,
|
|
5222
|
+
localStateName,
|
|
5223
|
+
phStateName,
|
|
5224
|
+
phDocumentTypeName,
|
|
5225
|
+
actionTypeName,
|
|
5226
|
+
actionsTypeName,
|
|
5227
|
+
actionsName,
|
|
5228
|
+
stateSchemaName: `${stateName}Schema`,
|
|
5229
|
+
phDocumentSchemaName: `${phDocumentTypeName}Schema`,
|
|
5230
|
+
isPhStateOfTypeFunctionName: `is${stateName}`,
|
|
5231
|
+
assertIsPhStateOfTypeFunctionName: `assertIs${stateName}`,
|
|
5232
|
+
isPhDocumentOfTypeFunctionName: `is${phDocumentTypeName}`,
|
|
5233
|
+
assertIsPhDocumentOfTypeFunctionName: `assertIs${phDocumentTypeName}`,
|
|
5234
|
+
useByIdHookName: `use${phDocumentTypeName}ById`,
|
|
5235
|
+
useSelectedHookName: `useSelected${phDocumentTypeName}`,
|
|
5236
|
+
useInSelectedDriveHookName: `use${phDocumentTypeName}sInSelectedDrive`,
|
|
5237
|
+
useInSelectedFolderHookName: `use${phDocumentTypeName}sInSelectedFolder`
|
|
5238
|
+
};
|
|
5239
|
+
}
|
|
5240
|
+
//#endregion
|
|
5077
5241
|
//#region src/templates/document-model/gen/modules/actions.ts
|
|
5078
|
-
function getActionTypeExport(
|
|
5079
|
-
const baseActionTypeName =
|
|
5080
|
-
const actionTypeName = getActionTypeName(
|
|
5081
|
-
const actionInputName = getActionInputName(
|
|
5082
|
-
return ts`export type ${actionTypeName} = ${baseActionTypeName} & { type: "${getActionType(
|
|
5242
|
+
function getActionTypeExport(operation) {
|
|
5243
|
+
const baseActionTypeName = operationHasAttachment(operation) ? "ActionWithAttachment" : "Action";
|
|
5244
|
+
const actionTypeName = getActionTypeName(operation);
|
|
5245
|
+
const actionInputName = getActionInputName(operation) ?? `"{}"`;
|
|
5246
|
+
return ts$1`export type ${actionTypeName} = ${baseActionTypeName} & { type: "${getActionType(operation)}"; input: ${actionInputName} };`.raw;
|
|
5083
5247
|
}
|
|
5084
|
-
function getActionTypeExports(
|
|
5085
|
-
return
|
|
5248
|
+
function getActionTypeExports(args) {
|
|
5249
|
+
return args.module.operations.map(getActionTypeExport).join("\n");
|
|
5086
5250
|
}
|
|
5087
|
-
function getModuleExportType(
|
|
5088
|
-
|
|
5251
|
+
function getModuleExportType(args) {
|
|
5252
|
+
const { pascalCaseDocumentType, module } = args;
|
|
5253
|
+
const actionTypeNames = module.operations.map(getActionTypeName).join(" |\n");
|
|
5254
|
+
return ts$1`export type ${pascalCaseDocumentType}${pascalCase(module.name)}Action = ${actionTypeNames};`.raw;
|
|
5089
5255
|
}
|
|
5090
|
-
function getDocumentModelActionTypeImportNames(
|
|
5256
|
+
function getDocumentModelActionTypeImportNames(args) {
|
|
5091
5257
|
const actionTypeImports = ["Action"];
|
|
5092
|
-
if (
|
|
5258
|
+
if (args.module.operations.some((a) => operationHasAttachment(a))) actionTypeImports.push("ActionWithAttachment");
|
|
5093
5259
|
return actionTypeImports.join(",\n");
|
|
5094
5260
|
}
|
|
5095
|
-
const documentModelOperationModuleActionsFileTemplate = (v) => ts`
|
|
5096
|
-
|
|
5261
|
+
const documentModelOperationModuleActionsFileTemplate = (v) => ts$1`
|
|
5262
|
+
/**
|
|
5263
|
+
* WARNING: DO NOT EDIT
|
|
5264
|
+
* This file is auto-generated and updated by codegen
|
|
5265
|
+
*/
|
|
5266
|
+
import type { ${getDocumentModelActionTypeImportNames(v)} } from 'document-model';
|
|
5097
5267
|
import type {
|
|
5098
|
-
${getActionInputTypeNames(v
|
|
5268
|
+
${getActionInputTypeNames(v)}
|
|
5099
5269
|
} from '../types.js';
|
|
5100
5270
|
|
|
5101
|
-
${getActionTypeExports(v
|
|
5271
|
+
${getActionTypeExports(v)}
|
|
5102
5272
|
|
|
5103
|
-
${getModuleExportType(v
|
|
5273
|
+
${getModuleExportType(v)}
|
|
5104
5274
|
`.raw;
|
|
5105
5275
|
//#endregion
|
|
5106
5276
|
//#region src/templates/document-model/gen/modules/creators.ts
|
|
5107
|
-
function makeDocumentModelTypeImports(
|
|
5277
|
+
function makeDocumentModelTypeImports(args) {
|
|
5108
5278
|
const actionTypeImports = ["createAction"];
|
|
5109
|
-
if (
|
|
5279
|
+
if (args.module.operations.some((a) => operationHasAttachment(a))) actionTypeImports.push("AttachmentInput");
|
|
5110
5280
|
return actionTypeImports.join(",\n");
|
|
5111
5281
|
}
|
|
5112
5282
|
function makeActionInputSchemaName(action) {
|
|
5113
|
-
if (!action.
|
|
5283
|
+
if (!action.name || !action.schema) return;
|
|
5114
5284
|
return `${pascalCase(action.name)}InputSchema`;
|
|
5115
5285
|
}
|
|
5116
5286
|
function makeActionInputTypeName(action) {
|
|
5117
|
-
if (!action.
|
|
5287
|
+
if (!action.name || !action.schema) return;
|
|
5118
5288
|
return `${pascalCase(action.name)}Input`;
|
|
5119
5289
|
}
|
|
5120
5290
|
function makeActionTypeName(action) {
|
|
5291
|
+
if (!action.name || !action.schema) return;
|
|
5121
5292
|
return `${pascalCase(action.name)}Action`;
|
|
5122
5293
|
}
|
|
5123
|
-
function makeActionInputSchemaImports(
|
|
5124
|
-
return
|
|
5125
|
-
}
|
|
5126
|
-
function makeActionInputTypeImports(
|
|
5127
|
-
return
|
|
5128
|
-
}
|
|
5129
|
-
function makeActionTypeImports(
|
|
5130
|
-
return
|
|
5131
|
-
}
|
|
5132
|
-
function makeActionCreatorWithInput(
|
|
5133
|
-
if (!
|
|
5134
|
-
const camelCaseActionName = camelCase(
|
|
5135
|
-
const constantCaseActionName = constantCase(
|
|
5136
|
-
const actionTypeName = makeActionTypeName(
|
|
5137
|
-
const inputSchemaName = makeActionInputSchemaName(
|
|
5138
|
-
const inputTypeName = makeActionInputTypeName(
|
|
5139
|
-
const
|
|
5140
|
-
|
|
5141
|
-
|
|
5294
|
+
function makeActionInputSchemaImports(args) {
|
|
5295
|
+
return args.module.operations.map(makeActionInputSchemaName).filter(Boolean).join(",\n");
|
|
5296
|
+
}
|
|
5297
|
+
function makeActionInputTypeImports(args) {
|
|
5298
|
+
return args.module.operations.map(makeActionInputTypeName).filter(Boolean).join(",\n");
|
|
5299
|
+
}
|
|
5300
|
+
function makeActionTypeImports(args) {
|
|
5301
|
+
return args.module.operations.map(makeActionTypeName).join(",\n");
|
|
5302
|
+
}
|
|
5303
|
+
function makeActionCreatorWithInput(operation) {
|
|
5304
|
+
if (!operation.name || !operation.schema) return;
|
|
5305
|
+
const camelCaseActionName = camelCase(operation.name);
|
|
5306
|
+
const constantCaseActionName = constantCase(operation.name);
|
|
5307
|
+
const actionTypeName = makeActionTypeName(operation);
|
|
5308
|
+
const inputSchemaName = makeActionInputSchemaName(operation);
|
|
5309
|
+
const inputTypeName = makeActionInputTypeName(operation);
|
|
5310
|
+
const hasAttachment = operationHasAttachment(operation);
|
|
5311
|
+
const argsArray = [operationHasEmptyInput(operation) ? `input: ${inputTypeName} = {}` : `input: ${inputTypeName}`];
|
|
5312
|
+
if (hasAttachment) argsArray.push(`attachments: AttachmentInput[]`);
|
|
5313
|
+
return ts$1`
|
|
5142
5314
|
export const ${camelCaseActionName} = (${argsArray.join(", ")}) =>
|
|
5143
5315
|
createAction<${actionTypeName}>(
|
|
5144
5316
|
"${constantCaseActionName}",
|
|
5145
5317
|
{...input},
|
|
5146
|
-
${
|
|
5318
|
+
${hasAttachment ? "attachments" : "undefined"},
|
|
5147
5319
|
${inputSchemaName},
|
|
5148
|
-
"${
|
|
5320
|
+
"${operation.scope}"
|
|
5149
5321
|
);`.raw;
|
|
5150
5322
|
}
|
|
5151
|
-
function makeActionCreatorWithoutInput(
|
|
5152
|
-
if (
|
|
5153
|
-
const camelCaseActionName = camelCase(
|
|
5154
|
-
const constantCaseActionName = constantCase(
|
|
5155
|
-
return ts`
|
|
5323
|
+
function makeActionCreatorWithoutInput(operation) {
|
|
5324
|
+
if (!operation.name || !operation.schema) return;
|
|
5325
|
+
const camelCaseActionName = camelCase(operation.name);
|
|
5326
|
+
const constantCaseActionName = constantCase(operation.name);
|
|
5327
|
+
return ts$1`
|
|
5156
5328
|
export const ${camelCaseActionName} = () =>
|
|
5157
|
-
createAction<${makeActionTypeName(
|
|
5329
|
+
createAction<${makeActionTypeName(operation)}>("${constantCaseActionName}");`.raw;
|
|
5158
5330
|
}
|
|
5159
|
-
function makeCreatorsForActionsWithInput(
|
|
5160
|
-
return
|
|
5331
|
+
function makeCreatorsForActionsWithInput(args) {
|
|
5332
|
+
return args.module.operations.filter((a) => isTruthy(a.schema)).map(makeActionCreatorWithInput).join("\n\n");
|
|
5161
5333
|
}
|
|
5162
|
-
function makeActionCreatorsWithoutInput(
|
|
5163
|
-
return
|
|
5334
|
+
function makeActionCreatorsWithoutInput(args) {
|
|
5335
|
+
return args.module.operations.filter((a) => !isTruthy(a.schema)).map(makeActionCreatorWithoutInput).join("\n\n");
|
|
5164
5336
|
}
|
|
5165
|
-
const documentModelOperationsModuleCreatorsFileTemplate = (v) => ts`
|
|
5166
|
-
|
|
5167
|
-
|
|
5337
|
+
const documentModelOperationsModuleCreatorsFileTemplate = (v) => ts$1`
|
|
5338
|
+
/**
|
|
5339
|
+
* WARNING: DO NOT EDIT
|
|
5340
|
+
* This file is auto-generated and updated by codegen
|
|
5341
|
+
*/
|
|
5342
|
+
import { ${makeDocumentModelTypeImports(v)} } from "document-model";
|
|
5168
5343
|
import {
|
|
5169
|
-
${makeActionInputSchemaImports(v
|
|
5344
|
+
${makeActionInputSchemaImports(v)}
|
|
5170
5345
|
} from '../schema/zod.js';
|
|
5171
5346
|
import type {
|
|
5172
|
-
${makeActionInputTypeImports(v
|
|
5347
|
+
${makeActionInputTypeImports(v)}
|
|
5173
5348
|
} from '../types.js';
|
|
5174
5349
|
import type {
|
|
5175
|
-
${makeActionTypeImports(v
|
|
5350
|
+
${makeActionTypeImports(v)}
|
|
5176
5351
|
} from './actions.js';
|
|
5177
5352
|
|
|
5178
|
-
${makeCreatorsForActionsWithInput(v
|
|
5353
|
+
${makeCreatorsForActionsWithInput(v)}
|
|
5179
5354
|
|
|
5180
|
-
${makeActionCreatorsWithoutInput(v
|
|
5355
|
+
${makeActionCreatorsWithoutInput(v)}
|
|
5181
5356
|
`.raw;
|
|
5182
5357
|
//#endregion
|
|
5183
5358
|
//#region src/templates/document-model/gen/modules/error.ts
|
|
@@ -5189,12 +5364,12 @@ function getErrorNames(errors) {
|
|
|
5189
5364
|
return errors.map(getErrorName).filter((name) => name !== void 0);
|
|
5190
5365
|
}
|
|
5191
5366
|
function getErrorCodeType(errors) {
|
|
5192
|
-
return ts`export type ErrorCode = ${getErrorNames(errors).map((name) => `"${name}"`).join(" |\n")};`.raw;
|
|
5367
|
+
return ts$1`export type ErrorCode = ${getErrorNames(errors).map((name) => `"${name}"`).join(" |\n")};`.raw;
|
|
5193
5368
|
}
|
|
5194
5369
|
function errorClassTemplate(error) {
|
|
5195
5370
|
const errorName = getErrorName(error);
|
|
5196
5371
|
if (!errorName) return;
|
|
5197
|
-
return ts`
|
|
5372
|
+
return ts$1`
|
|
5198
5373
|
export class ${errorName} extends Error implements ReducerError {
|
|
5199
5374
|
errorCode = "${errorName}" as ErrorCode;
|
|
5200
5375
|
constructor(message = "${errorName}") {
|
|
@@ -5206,13 +5381,14 @@ function errorClassTemplate(error) {
|
|
|
5206
5381
|
function getErrorClassImplementations(errors) {
|
|
5207
5382
|
return errors.map((error) => errorClassTemplate(error)).filter(Boolean).join("\n\n");
|
|
5208
5383
|
}
|
|
5209
|
-
function getErrorsImplementations(
|
|
5384
|
+
function getErrorsImplementations(args) {
|
|
5385
|
+
const errors = flatMap(args.module.operations, (o) => prop(o, "errors"));
|
|
5210
5386
|
if (!errors.length) return "";
|
|
5211
5387
|
const deduplicatedErrors = errors.reduce((acc, error) => {
|
|
5212
5388
|
if (!acc.some((e) => getErrorName(e) === getErrorName(error))) acc.push(error);
|
|
5213
5389
|
return acc;
|
|
5214
5390
|
}, new Array());
|
|
5215
|
-
return ts`
|
|
5391
|
+
return ts$1`
|
|
5216
5392
|
${getErrorCodeType(deduplicatedErrors)}
|
|
5217
5393
|
|
|
5218
5394
|
export interface ReducerError {
|
|
@@ -5222,74 +5398,82 @@ function getErrorsImplementations(errors) {
|
|
|
5222
5398
|
${getErrorClassImplementations(deduplicatedErrors)}
|
|
5223
5399
|
`.raw;
|
|
5224
5400
|
}
|
|
5225
|
-
function getActionErrorsExport(
|
|
5226
|
-
|
|
5401
|
+
function getActionErrorsExport(operation) {
|
|
5402
|
+
if (!operation.name) return;
|
|
5403
|
+
const errors = operation.errors;
|
|
5227
5404
|
if (errors.length === 0) return;
|
|
5228
|
-
return ts`
|
|
5229
|
-
${pascalCase(
|
|
5405
|
+
return ts$1`
|
|
5406
|
+
${pascalCase(operation.name)}: { ${getErrorNames(errors).filter(Boolean).join(",\n")} }
|
|
5230
5407
|
`.raw;
|
|
5231
5408
|
}
|
|
5232
|
-
function getErrorsExport(
|
|
5233
|
-
return ts`
|
|
5234
|
-
export const errors = { ${
|
|
5409
|
+
function getErrorsExport(args) {
|
|
5410
|
+
return ts$1`
|
|
5411
|
+
export const errors = { ${args.module.operations.map(getActionErrorsExport).filter(Boolean).join(",\n")} };
|
|
5235
5412
|
`.raw;
|
|
5236
5413
|
}
|
|
5237
|
-
const documentModelOperationsModuleErrorFileTemplate = (v) => ts`
|
|
5238
|
-
${getErrorsImplementations(v
|
|
5239
|
-
${getErrorsExport(v
|
|
5414
|
+
const documentModelOperationsModuleErrorFileTemplate = (v) => ts$1`
|
|
5415
|
+
${getErrorsImplementations(v)}
|
|
5416
|
+
${getErrorsExport(v)}
|
|
5240
5417
|
`.raw;
|
|
5241
5418
|
//#endregion
|
|
5242
5419
|
//#region src/templates/document-model/gen/modules/operations.ts
|
|
5243
5420
|
function getActionTypeNames(actions) {
|
|
5244
5421
|
return actions.map(getActionTypeName);
|
|
5245
5422
|
}
|
|
5246
|
-
function getActionTypeImports(
|
|
5247
|
-
return getActionTypeNames(
|
|
5423
|
+
function getActionTypeImports(args) {
|
|
5424
|
+
return getActionTypeNames(args.module.operations).join(",\n");
|
|
5248
5425
|
}
|
|
5249
5426
|
function getOperationsInterfaceName(pascalCaseDocumentType, module) {
|
|
5250
5427
|
return `${pascalCaseDocumentType}${pascalCase(module.name)}Operations`;
|
|
5251
5428
|
}
|
|
5252
5429
|
function getActionOperationFieldName(action) {
|
|
5430
|
+
if (!action.name) return;
|
|
5253
5431
|
return `${camelCase(action.name)}Operation`;
|
|
5254
5432
|
}
|
|
5255
5433
|
function getActionOperationStateTypeName(action, pascalCaseDocumentType) {
|
|
5256
|
-
if (!action.
|
|
5257
|
-
return `${pascalCaseDocumentType}
|
|
5434
|
+
if (!action.scope) return `${pascalCaseDocumentType}State`;
|
|
5435
|
+
return `${pascalCaseDocumentType}${pascalCase(action.scope)}State`;
|
|
5258
5436
|
}
|
|
5259
|
-
function getActionOperationStateTypeImports(
|
|
5260
|
-
const stateTypeNames =
|
|
5437
|
+
function getActionOperationStateTypeImports(args) {
|
|
5438
|
+
const stateTypeNames = args.module.operations.map((action) => getActionOperationStateTypeName(action, args.pascalCaseDocumentType));
|
|
5261
5439
|
return Array.from(new Set(stateTypeNames)).join(",\n");
|
|
5262
5440
|
}
|
|
5263
5441
|
function getActionOperationFunction(action, pascalCaseDocumentType) {
|
|
5264
|
-
return ts`
|
|
5442
|
+
return ts$1`
|
|
5265
5443
|
(state: ${getActionOperationStateTypeName(action, pascalCaseDocumentType)}, action: ${getActionTypeName(action)}, dispatch?: SignalDispatch) => void
|
|
5266
5444
|
`.raw;
|
|
5267
5445
|
}
|
|
5268
5446
|
function getOperationsInterfaceField(action, pascalCaseDocumentType) {
|
|
5269
|
-
return ts`
|
|
5447
|
+
return ts$1`
|
|
5270
5448
|
${getActionOperationFieldName(action)}: ${getActionOperationFunction(action, pascalCaseDocumentType)}
|
|
5271
5449
|
`.raw;
|
|
5272
5450
|
}
|
|
5273
|
-
function getOperationsInterfaceFields(
|
|
5274
|
-
return
|
|
5451
|
+
function getOperationsInterfaceFields(args) {
|
|
5452
|
+
return args.module.operations.map((action) => getOperationsInterfaceField(action, args.pascalCaseDocumentType)).join(",");
|
|
5275
5453
|
}
|
|
5276
|
-
const documentModelOperationsModuleOperationsFileTemplate = (v) => ts`
|
|
5454
|
+
const documentModelOperationsModuleOperationsFileTemplate = (v) => ts$1`
|
|
5455
|
+
/**
|
|
5456
|
+
* WARNING: DO NOT EDIT
|
|
5457
|
+
* This file is auto-generated and updated by codegen
|
|
5458
|
+
*/
|
|
5277
5459
|
import { type SignalDispatch } from 'document-model';
|
|
5278
5460
|
import type {
|
|
5279
|
-
${getActionTypeImports(v
|
|
5461
|
+
${getActionTypeImports(v)}
|
|
5280
5462
|
} from './actions.js';
|
|
5281
5463
|
import type {
|
|
5282
|
-
${getActionOperationStateTypeImports(v
|
|
5464
|
+
${getActionOperationStateTypeImports(v)}
|
|
5283
5465
|
} from "../types.js";
|
|
5284
5466
|
|
|
5285
5467
|
export interface ${getOperationsInterfaceName(v.pascalCaseDocumentType, v.module)} {
|
|
5286
|
-
${getOperationsInterfaceFields(v
|
|
5468
|
+
${getOperationsInterfaceFields(v)}
|
|
5287
5469
|
}
|
|
5288
5470
|
`.raw;
|
|
5289
5471
|
//#endregion
|
|
5290
5472
|
//#region src/templates/document-model/gen/ph-factories.ts
|
|
5291
|
-
const documentModelPhFactoriesFileTemplate = (v) => ts`
|
|
5473
|
+
const documentModelPhFactoriesFileTemplate = (v) => ts$1`
|
|
5292
5474
|
/**
|
|
5475
|
+
* WARNING: DO NOT EDIT
|
|
5476
|
+
* This file is auto-generated and updated by codegen
|
|
5293
5477
|
* Factory methods for creating ${v.phDocumentTypeName} instances
|
|
5294
5478
|
*/
|
|
5295
5479
|
import type {
|
|
@@ -5408,10 +5592,10 @@ function makeModulesOperationsImports(modules, camelCaseDocumentType) {
|
|
|
5408
5592
|
function makeOperationInputSchemaInvocation(operation) {
|
|
5409
5593
|
const operationInputSchema = makeOperationInputSchema(operation);
|
|
5410
5594
|
const constantCaseOperationName = makeConstantCaseOperationName(operation);
|
|
5411
|
-
if (operation.schema === null) return ts`
|
|
5595
|
+
if (operation.schema === null) return ts$1`
|
|
5412
5596
|
if (Object.keys(action.input).length > 0) throw new Error("Expected empty input for action ${constantCaseOperationName}");
|
|
5413
5597
|
`.raw;
|
|
5414
|
-
return ts`${operationInputSchema}().parse(action.input);`.raw;
|
|
5598
|
+
return ts$1`${operationInputSchema}().parse(action.input);`.raw;
|
|
5415
5599
|
}
|
|
5416
5600
|
function makeOperationsObjectName(module, camelCaseDocumentType) {
|
|
5417
5601
|
return `${camelCaseDocumentType}${pascalCase(module.name)}Operations`;
|
|
@@ -5420,12 +5604,12 @@ function makeOperationName(operation) {
|
|
|
5420
5604
|
return `${makeCamelCaseOperationName(operation)}Operation`;
|
|
5421
5605
|
}
|
|
5422
5606
|
function makeOperationInvocation(module, operation, camelCaseDocumentType) {
|
|
5423
|
-
return ts`
|
|
5607
|
+
return ts$1`
|
|
5424
5608
|
${makeOperationsObjectName(module, camelCaseDocumentType)}.${makeOperationName(operation)}((state as any)[action.scope], action as any, dispatch);
|
|
5425
5609
|
`.raw;
|
|
5426
5610
|
}
|
|
5427
5611
|
function makeModuleOperationCaseStatement(module, camelCaseDocumentType) {
|
|
5428
|
-
return module.operations.map((operation) => ts`
|
|
5612
|
+
return module.operations.map((operation) => ts$1`
|
|
5429
5613
|
case "${makeConstantCaseOperationName(operation)}": {
|
|
5430
5614
|
${makeOperationInputSchemaInvocation(operation)}
|
|
5431
5615
|
${makeOperationInvocation(module, operation, camelCaseDocumentType)}
|
|
@@ -5436,16 +5620,16 @@ function makeModuleOperationCaseStatement(module, camelCaseDocumentType) {
|
|
|
5436
5620
|
function makeModuleOperationsCaseStatements(modules, camelCaseDocumentType) {
|
|
5437
5621
|
return modules.map((module) => makeModuleOperationCaseStatement(module, camelCaseDocumentType).join("\n")).join("\n");
|
|
5438
5622
|
}
|
|
5439
|
-
const documentModelGenReducerFileTemplate = (v) => ts`
|
|
5623
|
+
const documentModelGenReducerFileTemplate = (v) => ts$1`
|
|
5440
5624
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
5441
5625
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
5442
5626
|
import type { Reducer, StateReducer } from "document-model";
|
|
5443
5627
|
import { isDocumentAction, createReducer } from "document-model";
|
|
5444
|
-
import type { ${v.phStateName} } from "${v.
|
|
5628
|
+
import type { ${v.phStateName} } from "${v.versionImportPath}";
|
|
5445
5629
|
|
|
5446
|
-
${makeModulesOperationsImports(v.modules, v.camelCaseDocumentType)}
|
|
5630
|
+
${makeModulesOperationsImports(v.specification.modules, v.camelCaseDocumentType)}
|
|
5447
5631
|
|
|
5448
|
-
${makeOperationInputSchemaImports(v.modules)}
|
|
5632
|
+
${makeOperationInputSchemaImports(v.specification.modules)}
|
|
5449
5633
|
|
|
5450
5634
|
const stateReducer: StateReducer<${v.phStateName}> =
|
|
5451
5635
|
(state, action, dispatch) => {
|
|
@@ -5453,7 +5637,7 @@ const stateReducer: StateReducer<${v.phStateName}> =
|
|
|
5453
5637
|
return state;
|
|
5454
5638
|
}
|
|
5455
5639
|
switch (action.type) {
|
|
5456
|
-
${makeModuleOperationsCaseStatements(v.modules, v.camelCaseDocumentType)}
|
|
5640
|
+
${makeModuleOperationsCaseStatements(v.specification.modules, v.camelCaseDocumentType)}
|
|
5457
5641
|
default:
|
|
5458
5642
|
return state;
|
|
5459
5643
|
}
|
|
@@ -5463,7 +5647,11 @@ export const reducer: Reducer<${v.phStateName}> = createReducer(stateReducer);
|
|
|
5463
5647
|
`.raw;
|
|
5464
5648
|
//#endregion
|
|
5465
5649
|
//#region src/templates/document-model/gen/schema/index.ts
|
|
5466
|
-
const documentModelSchemaIndexTemplate = ts`
|
|
5650
|
+
const documentModelSchemaIndexTemplate = ts$1`
|
|
5651
|
+
/**
|
|
5652
|
+
* WARNING: DO NOT EDIT
|
|
5653
|
+
* This file is auto-generated and updated by codegen
|
|
5654
|
+
*/
|
|
5467
5655
|
export * from "./types.js";
|
|
5468
5656
|
export * from "./zod.js";
|
|
5469
5657
|
`.raw;
|
|
@@ -5477,7 +5665,11 @@ function buildLocalStateTypeImport(hasLocalSchema, localStateName) {
|
|
|
5477
5665
|
if (!hasLocalSchema) return "";
|
|
5478
5666
|
return localStateName;
|
|
5479
5667
|
}
|
|
5480
|
-
const documentModelGenTypesTemplate = (v) => ts`
|
|
5668
|
+
const documentModelGenTypesTemplate = (v) => ts$1`
|
|
5669
|
+
/**
|
|
5670
|
+
* WARNING: DO NOT EDIT
|
|
5671
|
+
* This file is auto-generated and updated by codegen
|
|
5672
|
+
*/
|
|
5481
5673
|
import type { PHDocument, PHBaseState } from 'document-model';
|
|
5482
5674
|
import type { ${v.actionTypeName} } from './actions.js';
|
|
5483
5675
|
import type {
|
|
@@ -5505,7 +5697,11 @@ export type {
|
|
|
5505
5697
|
`.raw;
|
|
5506
5698
|
//#endregion
|
|
5507
5699
|
//#region src/templates/document-model/gen/utils.ts
|
|
5508
|
-
const documentModelGenUtilsTemplate = (v) => ts`
|
|
5700
|
+
const documentModelGenUtilsTemplate = (v) => ts$1`
|
|
5701
|
+
/**
|
|
5702
|
+
* WARNING: DO NOT EDIT
|
|
5703
|
+
* This file is auto-generated and updated by codegen
|
|
5704
|
+
*/
|
|
5509
5705
|
import type {
|
|
5510
5706
|
DocumentModelUtils,
|
|
5511
5707
|
} from "document-model";
|
|
@@ -5530,7 +5726,7 @@ export const initialGlobalState: ${v.globalStateName} = ${v.initialGlobalState};
|
|
|
5530
5726
|
export const initialLocalState: ${v.localStateName} = ${v.initialLocalState};
|
|
5531
5727
|
|
|
5532
5728
|
export const utils: DocumentModelUtils<${v.phStateName}> = {
|
|
5533
|
-
fileExtension: "${v.
|
|
5729
|
+
fileExtension: "${v.documentModelState.extension}",
|
|
5534
5730
|
createState(state) {
|
|
5535
5731
|
return { ...defaultBaseState(), global: { ...initialGlobalState, ...state?.global }, local: { ...initialLocalState, ...state?.local } };
|
|
5536
5732
|
},
|
|
@@ -5569,8 +5765,11 @@ export const utils: DocumentModelUtils<${v.phStateName}> = {
|
|
|
5569
5765
|
`.raw;
|
|
5570
5766
|
//#endregion
|
|
5571
5767
|
//#region src/templates/document-model/hooks.ts
|
|
5572
|
-
const documentModelHooksFileTemplate = (v) => ts`
|
|
5573
|
-
|
|
5768
|
+
const documentModelHooksFileTemplate = (v) => ts$1`
|
|
5769
|
+
/**
|
|
5770
|
+
* WARNING: DO NOT EDIT
|
|
5771
|
+
* This file is auto-generated and updated by codegen
|
|
5772
|
+
*/
|
|
5574
5773
|
import type { DocumentDispatch } from "@powerhousedao/reactor-browser";
|
|
5575
5774
|
import {
|
|
5576
5775
|
useDocumentById,
|
|
@@ -5581,7 +5780,7 @@ import {
|
|
|
5581
5780
|
import type {
|
|
5582
5781
|
${v.actionTypeName},
|
|
5583
5782
|
${v.phDocumentTypeName},
|
|
5584
|
-
} from "${v.
|
|
5783
|
+
} from "${v.versionImportPath}";
|
|
5585
5784
|
import {
|
|
5586
5785
|
${v.assertIsPhDocumentOfTypeFunctionName},
|
|
5587
5786
|
${v.isPhDocumentOfTypeFunctionName}
|
|
@@ -5621,17 +5820,26 @@ export function ${v.useInSelectedFolderHookName}() {
|
|
|
5621
5820
|
`.raw;
|
|
5622
5821
|
//#endregion
|
|
5623
5822
|
//#region src/templates/document-model/index.ts
|
|
5624
|
-
const documentModelIndexTemplate = ts`
|
|
5823
|
+
const documentModelIndexTemplate = ts$1`
|
|
5824
|
+
/**
|
|
5825
|
+
* WARNING: DO NOT EDIT
|
|
5826
|
+
* This file is auto-generated and updated by codegen
|
|
5827
|
+
*/
|
|
5625
5828
|
export * from "./gen/index.js";
|
|
5626
5829
|
export * from "./src/index.js";
|
|
5627
5830
|
export * from "./hooks.js";
|
|
5831
|
+
export * from "./module.js";
|
|
5628
5832
|
export { actions } from "./actions.js";
|
|
5629
5833
|
export { utils } from "./utils.js";
|
|
5630
5834
|
`.raw;
|
|
5631
5835
|
//#endregion
|
|
5632
5836
|
//#region src/templates/document-model/module.ts
|
|
5633
5837
|
function documentModelModuleFileTemplate({ phStateName, pascalCaseDocumentType, version }) {
|
|
5634
|
-
return ts`
|
|
5838
|
+
return ts$1`
|
|
5839
|
+
/**
|
|
5840
|
+
* WARNING: DO NOT EDIT
|
|
5841
|
+
* This file is auto-generated and updated by codegen
|
|
5842
|
+
*/
|
|
5635
5843
|
import type { DocumentModelModule } from "document-model";
|
|
5636
5844
|
import { createState, defaultBaseState } from "document-model";
|
|
5637
5845
|
import type { ${phStateName} } from "./gen/types.js";
|
|
@@ -5652,17 +5860,21 @@ function documentModelModuleFileTemplate({ phStateName, pascalCaseDocumentType,
|
|
|
5652
5860
|
}
|
|
5653
5861
|
//#endregion
|
|
5654
5862
|
//#region src/templates/document-model/src/index.ts
|
|
5655
|
-
const documentModelSrcIndexFileTemplate = ts`
|
|
5863
|
+
const documentModelSrcIndexFileTemplate = ts$1`
|
|
5864
|
+
/**
|
|
5865
|
+
* WARNING: DO NOT EDIT
|
|
5866
|
+
* This file is auto-generated and updated by codegen
|
|
5867
|
+
*/
|
|
5656
5868
|
export * from "./utils.js";
|
|
5657
5869
|
`.raw;
|
|
5658
5870
|
//#endregion
|
|
5659
5871
|
//#region src/templates/document-model/src/utils.ts
|
|
5660
|
-
const documentModelSrcUtilsTemplate = ts`
|
|
5872
|
+
const documentModelSrcUtilsTemplate = ts$1`
|
|
5661
5873
|
export {};
|
|
5662
5874
|
`.raw;
|
|
5663
5875
|
//#endregion
|
|
5664
5876
|
//#region src/templates/document-model/tests/document-model.test.ts
|
|
5665
|
-
const documentModelTestFileTemplate = (v) => ts`
|
|
5877
|
+
const documentModelTestFileTemplate = (v) => ts$1`
|
|
5666
5878
|
/**
|
|
5667
5879
|
* This is a scaffold file meant for customization:
|
|
5668
5880
|
* - change it by adding new tests or modifying the existing ones
|
|
@@ -5682,7 +5894,7 @@ import {
|
|
|
5682
5894
|
${v.assertIsPhDocumentOfTypeFunctionName},
|
|
5683
5895
|
${v.isPhStateOfTypeFunctionName},
|
|
5684
5896
|
${v.assertIsPhStateOfTypeFunctionName},
|
|
5685
|
-
} from "${v.
|
|
5897
|
+
} from "${v.versionImportPath}";
|
|
5686
5898
|
import { ZodError } from "zod";
|
|
5687
5899
|
|
|
5688
5900
|
describe("${v.pascalCaseDocumentType} Document Model", () => {
|
|
@@ -5786,19 +5998,20 @@ describe("${v.pascalCaseDocumentType} Document Model", () => {
|
|
|
5786
5998
|
function makeModuleOperationsTypeName(module) {
|
|
5787
5999
|
return `${pascalCase(module.name)}Operations`;
|
|
5788
6000
|
}
|
|
5789
|
-
function
|
|
5790
|
-
return
|
|
6001
|
+
function makeCamelCaseOperationNamesForImport(operations) {
|
|
6002
|
+
return pipe(operations, map(prop("name")), filter(isString), map((n) => camelCase(n)));
|
|
5791
6003
|
}
|
|
5792
|
-
function
|
|
5793
|
-
return
|
|
6004
|
+
function makeOperationInputSchemasForImport(operations) {
|
|
6005
|
+
return pipe(operations, map(prop("name")), filter(isString), map((n) => `${pascalCase(n)}InputSchema`));
|
|
5794
6006
|
}
|
|
5795
|
-
function
|
|
5796
|
-
|
|
5797
|
-
const
|
|
5798
|
-
const
|
|
6007
|
+
function makeTestCaseForOperation(operation, isPhDocumentOfTypeFunctionName) {
|
|
6008
|
+
if (operation.name === null) throw new Error(`Operation is missing name.`);
|
|
6009
|
+
const camelCaseActionName = camelCase(operation.name);
|
|
6010
|
+
const pascalCaseActionName = pascalCase(operation.name);
|
|
6011
|
+
const constantCaseActionName = constantCase(operation.name);
|
|
5799
6012
|
const actionInputSchemaName = `${pascalCaseActionName}InputSchema`;
|
|
5800
|
-
const scope =
|
|
5801
|
-
return ts`
|
|
6013
|
+
const scope = operation.scope;
|
|
6014
|
+
return ts$1`
|
|
5802
6015
|
it('should handle ${camelCaseActionName} operation', () => {
|
|
5803
6016
|
const document = utils.createDocument();
|
|
5804
6017
|
const input = generateMock(
|
|
@@ -5820,28 +6033,28 @@ function makeTestCaseForAction(action, isPhDocumentOfTypeFunctionName) {
|
|
|
5820
6033
|
});
|
|
5821
6034
|
`.raw;
|
|
5822
6035
|
}
|
|
5823
|
-
function
|
|
5824
|
-
const
|
|
5825
|
-
const inputSchemaNames =
|
|
6036
|
+
function makeOperationImportNames(v) {
|
|
6037
|
+
const operationNames = makeCamelCaseOperationNamesForImport(v.module.operations);
|
|
6038
|
+
const inputSchemaNames = makeOperationInputSchemasForImport(v.module.operations);
|
|
5826
6039
|
return [
|
|
5827
6040
|
"reducer",
|
|
5828
6041
|
"utils",
|
|
5829
6042
|
v.isPhDocumentOfTypeFunctionName,
|
|
5830
|
-
...
|
|
6043
|
+
...operationNames,
|
|
5831
6044
|
...inputSchemaNames
|
|
5832
6045
|
];
|
|
5833
6046
|
}
|
|
5834
|
-
function
|
|
5835
|
-
return ts`
|
|
6047
|
+
function makeOperationsImports(v) {
|
|
6048
|
+
return ts$1`
|
|
5836
6049
|
import {
|
|
5837
|
-
${
|
|
5838
|
-
} from "${v.
|
|
6050
|
+
${makeOperationImportNames(v).join("\n")}
|
|
6051
|
+
} from "${v.versionImportPath}";
|
|
5839
6052
|
`.raw;
|
|
5840
6053
|
}
|
|
5841
|
-
function
|
|
5842
|
-
return
|
|
6054
|
+
function makeTestCasesForOperations(operations, isPhDocumentOfTypeFunctionName) {
|
|
6055
|
+
return operations.map((operation) => makeTestCaseForOperation(operation, isPhDocumentOfTypeFunctionName)).join("\n\n");
|
|
5843
6056
|
}
|
|
5844
|
-
const documentModelOperationsModuleTestFileTemplate = (v) => ts`
|
|
6057
|
+
const documentModelOperationsModuleTestFileTemplate = (v) => ts$1`
|
|
5845
6058
|
/**
|
|
5846
6059
|
* This is a scaffold file meant for customization:
|
|
5847
6060
|
* - change it by adding new tests or modifying the existing ones
|
|
@@ -5853,23 +6066,27 @@ import {
|
|
|
5853
6066
|
reducer,
|
|
5854
6067
|
utils,
|
|
5855
6068
|
${v.isPhDocumentOfTypeFunctionName},
|
|
5856
|
-
${
|
|
5857
|
-
${
|
|
5858
|
-
} from "${v.
|
|
6069
|
+
${makeCamelCaseOperationNamesForImport(v.module.operations)},
|
|
6070
|
+
${makeOperationInputSchemasForImport(v.module.operations)},
|
|
6071
|
+
} from "${v.versionImportPath}";
|
|
5859
6072
|
|
|
5860
6073
|
describe("${makeModuleOperationsTypeName(v.module)}", () => {
|
|
5861
|
-
${
|
|
6074
|
+
${makeTestCasesForOperations(v.module.operations, v.isPhDocumentOfTypeFunctionName)}
|
|
5862
6075
|
});
|
|
5863
6076
|
|
|
5864
6077
|
`.raw;
|
|
5865
6078
|
//#endregion
|
|
5866
6079
|
//#region src/templates/document-model/upgrades/upgrade-manifest.ts
|
|
5867
|
-
const upgradeManifestTemplate = (v) => ts`
|
|
6080
|
+
const upgradeManifestTemplate = (v) => ts$1`
|
|
6081
|
+
/**
|
|
6082
|
+
* WARNING: DO NOT EDIT
|
|
6083
|
+
* This file is auto-generated and updated by codegen
|
|
6084
|
+
*/
|
|
5868
6085
|
import type { UpgradeManifest } from "document-model";
|
|
5869
6086
|
import { latestVersion, supportedVersions } from "./versions.js";
|
|
5870
6087
|
|
|
5871
6088
|
export const ${v.upgradeManifestName}: UpgradeManifest<typeof supportedVersions> = {
|
|
5872
|
-
documentType: "${v.
|
|
6089
|
+
documentType: "${v.documentModelState.id}",
|
|
5873
6090
|
latestVersion,
|
|
5874
6091
|
supportedVersions,
|
|
5875
6092
|
upgrades: {},
|
|
@@ -5877,13 +6094,13 @@ const upgradeManifestTemplate = (v) => ts`
|
|
|
5877
6094
|
`.raw;
|
|
5878
6095
|
//#endregion
|
|
5879
6096
|
//#region src/templates/document-model/upgrades/upgrade-transition.ts
|
|
5880
|
-
const upgradeTransitionTemplate = (v) => ts`
|
|
6097
|
+
const upgradeTransitionTemplate = (v) => ts$1`
|
|
5881
6098
|
import type { Action, PHDocument, UpgradeTransition } from "document-model";
|
|
5882
|
-
import type { ${v.phStateName} as StateV${v.
|
|
5883
|
-
import type { ${v.phStateName} as StateV${v.version} } from "${v.
|
|
6099
|
+
import type { ${v.phStateName} as StateV${v.version - 1} } from "${v.documentModelImportPath}/v${v.version - 1}";
|
|
6100
|
+
import type { ${v.phStateName} as StateV${v.version} } from "${v.documentModelImportPath}/v${v.version}";
|
|
5884
6101
|
|
|
5885
6102
|
function upgradeReducer(
|
|
5886
|
-
document: PHDocument<StateV${v.
|
|
6103
|
+
document: PHDocument<StateV${v.version - 1}>,
|
|
5887
6104
|
action: Action,
|
|
5888
6105
|
): PHDocument<StateV${v.version}> {
|
|
5889
6106
|
return {
|
|
@@ -5899,7 +6116,11 @@ export const v${v.version}: UpgradeTransition = {
|
|
|
5899
6116
|
`.raw;
|
|
5900
6117
|
//#endregion
|
|
5901
6118
|
//#region src/templates/document-model/utils.ts
|
|
5902
|
-
const documentModelUtilsTemplate = ({ phStateName, pascalCaseDocumentType }) => ts`
|
|
6119
|
+
const documentModelUtilsTemplate = ({ phStateName, pascalCaseDocumentType }) => ts$1`
|
|
6120
|
+
/**
|
|
6121
|
+
* WARNING: DO NOT EDIT
|
|
6122
|
+
* This file is auto-generated and updated by codegen
|
|
6123
|
+
*/
|
|
5903
6124
|
import type { DocumentModelUtils } from "document-model";
|
|
5904
6125
|
import type { ${phStateName} } from "./gen/types.js";
|
|
5905
6126
|
import { utils as genUtils } from "./gen/utils.js";
|
|
@@ -5916,7 +6137,7 @@ function getDocumentType(documentTypes) {
|
|
|
5916
6137
|
}
|
|
5917
6138
|
//#endregion
|
|
5918
6139
|
//#region src/templates/processors/analytics/factory.ts
|
|
5919
|
-
const analyticsFactoryTemplate = (v) => ts`
|
|
6140
|
+
const analyticsFactoryTemplate = (v) => ts$1`
|
|
5920
6141
|
import type {
|
|
5921
6142
|
ProcessorApp,
|
|
5922
6143
|
ProcessorFactoryBuilder,
|
|
@@ -5942,13 +6163,17 @@ export const ${v.camelCaseName}FactoryBuilder: ProcessorFactoryBuilder = (module
|
|
|
5942
6163
|
`.raw;
|
|
5943
6164
|
//#endregion
|
|
5944
6165
|
//#region src/templates/processors/analytics/index.ts
|
|
5945
|
-
const analyticsIndexTemplate = ts`
|
|
6166
|
+
const analyticsIndexTemplate = ts$1`
|
|
6167
|
+
/**
|
|
6168
|
+
* WARNING: DO NOT EDIT
|
|
6169
|
+
* This file is auto-generated and updated by codegen
|
|
6170
|
+
*/
|
|
5946
6171
|
export * from "./factory.js";
|
|
5947
6172
|
export * from "./processor.js";
|
|
5948
6173
|
`.raw;
|
|
5949
6174
|
//#endregion
|
|
5950
6175
|
//#region src/templates/processors/analytics/processor.ts
|
|
5951
|
-
const analyticsProcessorTemplate = (v) => ts`
|
|
6176
|
+
const analyticsProcessorTemplate = (v) => ts$1`
|
|
5952
6177
|
import type { AnalyticsSeriesInput, AnalyticsPath, IAnalyticsStore } from "@powerhousedao/analytics-engine-core";
|
|
5953
6178
|
import type { OperationWithContext, IProcessor } from "@powerhousedao/reactor-browser";
|
|
5954
6179
|
|
|
@@ -5980,19 +6205,22 @@ export class ${v.pascalCaseName} implements IProcessor {
|
|
|
5980
6205
|
`.raw;
|
|
5981
6206
|
//#endregion
|
|
5982
6207
|
//#region src/templates/processors/factory-builders.ts
|
|
5983
|
-
const factoryBuildersTemplate = ts`
|
|
6208
|
+
const factoryBuildersTemplate = ts$1`
|
|
6209
|
+
/**
|
|
6210
|
+
* WARNING: DO NOT EDIT
|
|
6211
|
+
* This file is auto-generated and updated by codegen
|
|
6212
|
+
*/
|
|
5984
6213
|
import type { ProcessorFactoryBuilder } from "@powerhousedao/reactor";
|
|
5985
6214
|
|
|
5986
6215
|
export const processorFactoryBuilders: ProcessorFactoryBuilder[] = [];
|
|
5987
6216
|
`.raw;
|
|
5988
6217
|
//#endregion
|
|
5989
6218
|
//#region src/templates/processors/factory.ts
|
|
5990
|
-
const processorsFactoryTemplate = ts`
|
|
6219
|
+
const processorsFactoryTemplate = ts$1`
|
|
5991
6220
|
/**
|
|
5992
|
-
*
|
|
5993
|
-
*
|
|
6221
|
+
* WARNING: DO NOT EDIT
|
|
6222
|
+
* This file is auto-generated and updated by codegen
|
|
5994
6223
|
*/
|
|
5995
|
-
|
|
5996
6224
|
import type {
|
|
5997
6225
|
IProcessorHostModule,
|
|
5998
6226
|
ProcessorRecord,
|
|
@@ -6027,17 +6255,16 @@ export const processorFactory = async (module: IProcessorHostModule) => {
|
|
|
6027
6255
|
`.raw;
|
|
6028
6256
|
//#endregion
|
|
6029
6257
|
//#region src/templates/processors/index.ts
|
|
6030
|
-
const processorsIndexTemplate = ts`
|
|
6258
|
+
const processorsIndexTemplate = ts$1`
|
|
6031
6259
|
/**
|
|
6032
|
-
*
|
|
6260
|
+
* WARNING: DO NOT EDIT
|
|
6033
6261
|
* This file is auto-generated and updated by codegen
|
|
6034
6262
|
*/
|
|
6035
|
-
|
|
6036
6263
|
export { processorFactory } from "./factory.js";
|
|
6037
6264
|
`.raw;
|
|
6038
6265
|
//#endregion
|
|
6039
6266
|
//#region src/templates/processors/relational-db/factory.ts
|
|
6040
|
-
const relationalDbFactoryTemplate = (v) => ts`
|
|
6267
|
+
const relationalDbFactoryTemplate = (v) => ts$1`
|
|
6041
6268
|
import type {
|
|
6042
6269
|
IProcessorHostModule,
|
|
6043
6270
|
ProcessorApp,
|
|
@@ -6077,13 +6304,17 @@ export const ${v.camelCaseName}FactoryBuilder: ProcessorFactoryBuilder = (module
|
|
|
6077
6304
|
`.raw;
|
|
6078
6305
|
//#endregion
|
|
6079
6306
|
//#region src/templates/processors/relational-db/index.ts
|
|
6080
|
-
const relationalDbIndexTemplate = ts`
|
|
6307
|
+
const relationalDbIndexTemplate = ts$1`
|
|
6308
|
+
/**
|
|
6309
|
+
* WARNING: DO NOT EDIT
|
|
6310
|
+
* This file is auto-generated and updated by codegen
|
|
6311
|
+
*/
|
|
6081
6312
|
export * from "./factory.js";
|
|
6082
6313
|
export * from "./processor.js";
|
|
6083
6314
|
`.raw;
|
|
6084
6315
|
//#endregion
|
|
6085
6316
|
//#region src/templates/processors/relational-db/migrations.ts
|
|
6086
|
-
const relationalDbMigrationsTemplate = () => ts`
|
|
6317
|
+
const relationalDbMigrationsTemplate = () => ts$1`
|
|
6087
6318
|
import type { IRelationalDb } from "@powerhousedao/reactor-browser"
|
|
6088
6319
|
|
|
6089
6320
|
export async function up(db: IRelationalDb<any>): Promise<void> {
|
|
@@ -6107,7 +6338,7 @@ export async function down(db: IRelationalDb<any>): Promise<void> {
|
|
|
6107
6338
|
//#endregion
|
|
6108
6339
|
//#region src/templates/processors/relational-db/processor.ts
|
|
6109
6340
|
const defaultNamespaceComment = "// Default namespace: `${this.name}_${driveId.replaceAll(\"-\", \"_\")}`";
|
|
6110
|
-
const relationalDbProcessorTemplate = (v) => ts`
|
|
6341
|
+
const relationalDbProcessorTemplate = (v) => ts$1`
|
|
6111
6342
|
import { RelationalDbProcessor } from "@powerhousedao/reactor-browser";
|
|
6112
6343
|
import type { OperationWithContext } from "document-model";
|
|
6113
6344
|
import { up } from "./migrations.js";
|
|
@@ -6134,7 +6365,7 @@ export class ${v.pascalCaseName} extends RelationalDbProcessor<DB> {
|
|
|
6134
6365
|
`.raw;
|
|
6135
6366
|
//#endregion
|
|
6136
6367
|
//#region src/templates/processors/relational-db/schema.ts
|
|
6137
|
-
const relationalDbSchemaTemplate = () => ts`
|
|
6368
|
+
const relationalDbSchemaTemplate = () => ts$1`
|
|
6138
6369
|
export interface Todo {
|
|
6139
6370
|
status: boolean | null;
|
|
6140
6371
|
task: string;
|
|
@@ -6146,7 +6377,7 @@ export interface DB {
|
|
|
6146
6377
|
`.raw;
|
|
6147
6378
|
//#endregion
|
|
6148
6379
|
//#region src/templates/subgraphs/index-file.ts
|
|
6149
|
-
const subgraphIndexFileTemplate = (v) => ts`
|
|
6380
|
+
const subgraphIndexFileTemplate = (v) => ts$1`
|
|
6150
6381
|
import { BaseSubgraph } from "@powerhousedao/reactor-api";
|
|
6151
6382
|
import type { DocumentNode } from "graphql";
|
|
6152
6383
|
import { schema } from "./schema.js";
|
|
@@ -6163,7 +6394,7 @@ export class ${v.pascalCaseName}Subgraph extends BaseSubgraph {
|
|
|
6163
6394
|
`.raw;
|
|
6164
6395
|
//#endregion
|
|
6165
6396
|
//#region src/templates/subgraphs/lib-file.ts
|
|
6166
|
-
const subgraphLibFileTemplate = () => ts`
|
|
6397
|
+
const subgraphLibFileTemplate = () => ts$1`
|
|
6167
6398
|
/**
|
|
6168
6399
|
* This is a scaffold file meant for customization.
|
|
6169
6400
|
* Delete the file and run the code generator again to have it reset
|
|
@@ -6171,7 +6402,7 @@ const subgraphLibFileTemplate = () => ts`
|
|
|
6171
6402
|
`.raw;
|
|
6172
6403
|
//#endregion
|
|
6173
6404
|
//#region src/templates/subgraphs/custom-schema.ts
|
|
6174
|
-
const customSubgraphSchemaTemplate = (v) => ts`
|
|
6405
|
+
const customSubgraphSchemaTemplate = (v) => ts$1`
|
|
6175
6406
|
import { gql } from "graphql-tag";
|
|
6176
6407
|
import type { DocumentNode } from "graphql";
|
|
6177
6408
|
|
|
@@ -6191,7 +6422,7 @@ type Query {
|
|
|
6191
6422
|
`.raw;
|
|
6192
6423
|
//#endregion
|
|
6193
6424
|
//#region src/templates/subgraphs/custom-resolvers.ts
|
|
6194
|
-
const customSubgraphResolversTemplate = (v) => ts`
|
|
6425
|
+
const customSubgraphResolversTemplate = (v) => ts$1`
|
|
6195
6426
|
import { type ISubgraph } from "@powerhousedao/reactor-api";
|
|
6196
6427
|
|
|
6197
6428
|
export const getResolvers = (subgraph: ISubgraph): Record<string, unknown> => {
|
|
@@ -6210,178 +6441,1886 @@ export const getResolvers = (subgraph: ISubgraph): Record<string, unknown> => {
|
|
|
6210
6441
|
};
|
|
6211
6442
|
`.raw;
|
|
6212
6443
|
//#endregion
|
|
6213
|
-
//#region src/
|
|
6214
|
-
const
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
getDocuments(driveId: String): [${v.pascalCaseDocumentType}!]
|
|
6444
|
+
//#region src/utils/cli.ts
|
|
6445
|
+
const configSpec = {
|
|
6446
|
+
"--document-models": String,
|
|
6447
|
+
"--editors": String,
|
|
6448
|
+
"--interactive": Boolean,
|
|
6449
|
+
"--skip-format": Boolean,
|
|
6450
|
+
"--watch": Boolean,
|
|
6451
|
+
"-i": "--interactive",
|
|
6452
|
+
"-sf": "--skip-format",
|
|
6453
|
+
"-w": "--watch"
|
|
6454
|
+
};
|
|
6455
|
+
function parseArgs(argv, spec) {
|
|
6456
|
+
return arg(spec, {
|
|
6457
|
+
permissive: true,
|
|
6458
|
+
argv
|
|
6459
|
+
});
|
|
6230
6460
|
}
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6461
|
+
function parseConfig(argv) {
|
|
6462
|
+
const config = {};
|
|
6463
|
+
const args = parseArgs(argv, configSpec);
|
|
6464
|
+
if ("--document-models" in args) config.documentModelsDir = args["--document-models"];
|
|
6465
|
+
if ("--editors" in args) config.editorsDir = args["--editors"];
|
|
6466
|
+
if ("--skip-format" in args) config.skipFormat = true;
|
|
6467
|
+
if ("--interactive" in args) config.interactive = true;
|
|
6468
|
+
if ("--watch" in args) config.watch = true;
|
|
6469
|
+
return config;
|
|
6234
6470
|
}
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6471
|
+
//#endregion
|
|
6472
|
+
//#region src/utils/constants.ts
|
|
6473
|
+
/** Document model metadata for the `powerhouse/document-model` document type.
|
|
6474
|
+
*
|
|
6475
|
+
* Assumed to always be present during codegen.
|
|
6476
|
+
*/
|
|
6477
|
+
const documentModelDocumentTypeMetadata = {
|
|
6478
|
+
documentModelId: "powerhouse/document-model",
|
|
6479
|
+
documentModelDocumentTypeName: "DocumentModelDocument",
|
|
6480
|
+
documentModelDirName: "document-model",
|
|
6481
|
+
documentModelImportPath: "document-model"
|
|
6482
|
+
};
|
|
6483
|
+
//#endregion
|
|
6484
|
+
//#region src/utils/document-type-metadata.ts
|
|
6485
|
+
/** Gets the document model metadata for the --document-type argument
|
|
6486
|
+
* passed to the `generate --editor` and `generate --app` commands.
|
|
6487
|
+
*/
|
|
6488
|
+
function getDocumentTypeMetadata({ project, documentModelId }) {
|
|
6489
|
+
const { directory: documentModelsDir } = getOrCreateDirectory(project, "document-models");
|
|
6490
|
+
const documentModelVariableNames = pipe(readdirSync(documentModelsDir.getPath(), { withFileTypes: true }), filter((dirent) => dirent.isDirectory()), map((dir) => join(dir.parentPath, `${dir.name}/${dir.name}.json`)), filter((srcPath) => statSync(srcPath, { throwIfNoEntry: false })?.isFile() ?? false), map((srcPath) => loadJsonFileSync(srcPath)), filter((stateFile) => DocumentModelGlobalStateSchema().safeParse(stateFile).success === true), find((state) => state.id === documentModelId), prop("name"), when(isString, (name) => getDocumentModelVariableNames(name)));
|
|
6491
|
+
if (!documentModelVariableNames) throw new Error(`Failed to get document type metadata for document type: ${documentModelId}.`);
|
|
6492
|
+
const { kebabCaseDocumentType, phDocumentTypeName } = documentModelVariableNames;
|
|
6493
|
+
return {
|
|
6494
|
+
documentModelId,
|
|
6495
|
+
documentModelDocumentTypeName: phDocumentTypeName,
|
|
6496
|
+
documentModelDirName: kebabCaseDocumentType,
|
|
6497
|
+
documentModelImportPath: join("document-models", kebabCaseDocumentType)
|
|
6498
|
+
};
|
|
6244
6499
|
}
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6500
|
+
//#endregion
|
|
6501
|
+
//#region src/utils/format-with-prettier.ts
|
|
6502
|
+
/** Formats the text of a ts-morph source file with prettier before writing the text to memory */
|
|
6503
|
+
async function formatSourceFileWithPrettier(sourceFile) {
|
|
6504
|
+
sourceFile.organizeImports();
|
|
6505
|
+
const formattedText = await formatSafe(sourceFile.getFullText());
|
|
6506
|
+
sourceFile.replaceWithText(formattedText);
|
|
6507
|
+
}
|
|
6508
|
+
async function formatSafe(sourceText, parser = "typescript") {
|
|
6509
|
+
try {
|
|
6510
|
+
return await format(sourceText, { parser });
|
|
6511
|
+
} catch (error) {
|
|
6512
|
+
console.error(error);
|
|
6513
|
+
return sourceText;
|
|
6514
|
+
}
|
|
6515
|
+
}
|
|
6516
|
+
async function runPrettier() {
|
|
6517
|
+
await spawnAsync("npx", [
|
|
6518
|
+
"prettier",
|
|
6519
|
+
"--write",
|
|
6520
|
+
"."
|
|
6521
|
+
]);
|
|
6522
|
+
}
|
|
6523
|
+
//#endregion
|
|
6524
|
+
//#region src/utils/source-files.ts
|
|
6525
|
+
/** Gets a SourceFile by name in a ts-morph Project, or creates a new one
|
|
6526
|
+
* if none with that path exists.
|
|
6527
|
+
*/
|
|
6528
|
+
function getOrCreateSourceFile(project, filePath) {
|
|
6529
|
+
const dirName = path.dirname(filePath);
|
|
6530
|
+
if (!project.getDirectory(dirName)) project.createDirectory(dirName);
|
|
6531
|
+
const sourceFile = project.getSourceFile(filePath);
|
|
6532
|
+
if (!sourceFile) return {
|
|
6533
|
+
alreadyExists: false,
|
|
6534
|
+
sourceFile: project.createSourceFile(filePath, "", { overwrite: true })
|
|
6535
|
+
};
|
|
6536
|
+
return {
|
|
6537
|
+
alreadyExists: true,
|
|
6538
|
+
sourceFile
|
|
6539
|
+
};
|
|
6540
|
+
}
|
|
6541
|
+
/** Gets a Directory by name in a ts-morph Project, or creates a new one
|
|
6542
|
+
* if none with that path exists.
|
|
6543
|
+
*/
|
|
6544
|
+
function getOrCreateDirectory(project, dirPath) {
|
|
6545
|
+
const directory = project.getDirectory(dirPath);
|
|
6546
|
+
if (!directory) return {
|
|
6547
|
+
alreadyExists: false,
|
|
6548
|
+
directory: project.createDirectory(dirPath)
|
|
6549
|
+
};
|
|
6550
|
+
return {
|
|
6551
|
+
alreadyExists: true,
|
|
6552
|
+
directory
|
|
6553
|
+
};
|
|
6554
|
+
}
|
|
6555
|
+
/** Ensures that the directories at the given paths exist within the
|
|
6556
|
+
* ts-morph Project
|
|
6557
|
+
*/
|
|
6558
|
+
async function ensureDirectoriesExist(project, ...pathsToEnsure) {
|
|
6559
|
+
for (const dirPath of pathsToEnsure) if (!project.getDirectory(dirPath)) await project.createDirectory(dirPath).save();
|
|
6560
|
+
}
|
|
6561
|
+
function getPreviousVersionSourceFile(args) {
|
|
6562
|
+
const { project, version, filePath } = args;
|
|
6563
|
+
const previousVersion = version - 1;
|
|
6564
|
+
if (previousVersion < 1) return;
|
|
6565
|
+
const previousVersionFilePath = filePath.replace(`/v${version}/`, `/v${previousVersion}/`);
|
|
6566
|
+
return project.getSourceFile(previousVersionFilePath);
|
|
6567
|
+
}
|
|
6568
|
+
//#endregion
|
|
6569
|
+
//#region src/utils/syntax-builders.ts
|
|
6570
|
+
/** Builds a ts-morph ObjectLiteralExpression from a ts/js object
|
|
6571
|
+
* Useful for substituting the value of a runtime object in templates
|
|
6572
|
+
*/
|
|
6573
|
+
function buildObjectLiteral(inputObject, sourceFile) {
|
|
6574
|
+
const propertyAssignments = [];
|
|
6575
|
+
for (const [key, value] of Object.entries(inputObject)) {
|
|
6576
|
+
const propertyAssignment = buildPropertyAssignment(key, value);
|
|
6577
|
+
propertyAssignments.push(propertyAssignment);
|
|
6578
|
+
}
|
|
6579
|
+
const objectLiteral = ts.factory.createObjectLiteralExpression(propertyAssignments, true);
|
|
6580
|
+
return buildNodePrinter(sourceFile)(objectLiteral);
|
|
6581
|
+
}
|
|
6582
|
+
function buildFalse() {
|
|
6583
|
+
return ts.factory.createFalse();
|
|
6584
|
+
}
|
|
6585
|
+
function buildTrue() {
|
|
6586
|
+
return ts.factory.createTrue();
|
|
6587
|
+
}
|
|
6588
|
+
function buildBoolean(value) {
|
|
6589
|
+
return value ? buildTrue() : buildFalse();
|
|
6590
|
+
}
|
|
6591
|
+
function buildNull() {
|
|
6592
|
+
return ts.factory.createNull();
|
|
6593
|
+
}
|
|
6594
|
+
function buildUndefined() {
|
|
6595
|
+
return ts.factory.createIdentifier("undefined");
|
|
6596
|
+
}
|
|
6597
|
+
function buildNumericLiteral(value) {
|
|
6598
|
+
return ts.factory.createNumericLiteral(value);
|
|
6599
|
+
}
|
|
6600
|
+
function buildStringLiteral(value) {
|
|
6601
|
+
return ts.factory.createStringLiteral(value);
|
|
6602
|
+
}
|
|
6603
|
+
function buildArrayLiteral(elements) {
|
|
6604
|
+
return ts.factory.createArrayLiteralExpression(elements, true);
|
|
6605
|
+
}
|
|
6606
|
+
function valueToExpression(value) {
|
|
6607
|
+
if (value === null) return buildNull();
|
|
6608
|
+
if (value === void 0) return buildUndefined();
|
|
6609
|
+
if (typeof value === "boolean") return buildBoolean(value);
|
|
6610
|
+
if (typeof value === "string") return buildStringLiteral(value);
|
|
6611
|
+
if (typeof value === "number") return buildNumericLiteral(value);
|
|
6612
|
+
if (Array.isArray(value)) return buildArrayLiteral(value.map((item) => valueToExpression(item)));
|
|
6613
|
+
if (typeof value === "object") return ts.factory.createObjectLiteralExpression(Object.entries(value).map(([key, v]) => {
|
|
6614
|
+
const name = ts.factory.createIdentifier(key);
|
|
6615
|
+
return ts.factory.createPropertyAssignment(name, valueToExpression(v));
|
|
6616
|
+
}), true);
|
|
6617
|
+
throw new Error("Invalid value passed: ", value);
|
|
6618
|
+
}
|
|
6619
|
+
function buildPropertyAssignment(name, value) {
|
|
6620
|
+
const nameIdentifier = ts.factory.createIdentifier(name);
|
|
6621
|
+
const valueExpression = valueToExpression(value);
|
|
6622
|
+
return ts.factory.createPropertyAssignment(nameIdentifier, valueExpression);
|
|
6623
|
+
}
|
|
6624
|
+
function buildNodePrinter(sourceFile) {
|
|
6625
|
+
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
|
|
6626
|
+
return (node) => printer.printNode(ts.EmitHint.Unspecified, node, sourceFile.compilerNode);
|
|
6627
|
+
}
|
|
6628
|
+
//#endregion
|
|
6629
|
+
//#region src/utils/syntax-getters.ts
|
|
6630
|
+
/** Returns a ts-morph ObjectLiteralExpression from a variable statement
|
|
6631
|
+
* if the type matches
|
|
6632
|
+
*/
|
|
6633
|
+
function getObjectLiteral(statement) {
|
|
6634
|
+
return statement?.getDeclarations().at(0)?.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
|
|
6635
|
+
}
|
|
6636
|
+
/** Returns the value of a property in a ts-morph ObjectLiteralExpression of type T if it exists */
|
|
6637
|
+
function getObjectProperty(object, propertyName, propertyType) {
|
|
6638
|
+
return object?.getProperty(propertyName)?.asKind(SyntaxKind.PropertyAssignment)?.getChildren().find((child) => child.getKind() === propertyType)?.asKindOrThrow(propertyType);
|
|
6639
|
+
}
|
|
6640
|
+
function getVariableDeclarationByTypeName(sourceFile, typeName) {
|
|
6641
|
+
return sourceFile.getVariableDeclaration((declaration) => {
|
|
6642
|
+
if ((declaration.getTypeNode()?.getText() ?? "").includes(typeName)) return true;
|
|
6643
|
+
return declaration.getType().getText().includes(typeName);
|
|
6644
|
+
});
|
|
6645
|
+
}
|
|
6646
|
+
//#endregion
|
|
6647
|
+
//#region src/utils/ts-morph-project.ts
|
|
6648
|
+
const DEFAULT_PROJECT_OPTIONS = {
|
|
6649
|
+
skipAddingFilesFromTsConfig: true,
|
|
6650
|
+
skipLoadingLibFiles: true,
|
|
6651
|
+
manipulationSettings: {
|
|
6652
|
+
useTrailingCommas: true,
|
|
6653
|
+
indentationText: IndentationText.TwoSpaces,
|
|
6654
|
+
indentMultiLineObjectLiteralBeginningOnBlankLine: true
|
|
6655
|
+
}
|
|
6249
6656
|
};
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
}
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
}
|
|
6284
|
-
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6288
|
-
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6308
|
-
|
|
6309
|
-
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
${
|
|
6372
|
-
|
|
6373
|
-
|
|
6657
|
+
/** Returns the minimal typescript config for use in ts-morph file generation */
|
|
6658
|
+
function getDefaultProjectOptions(tsConfigFilePath) {
|
|
6659
|
+
return {
|
|
6660
|
+
...DEFAULT_PROJECT_OPTIONS,
|
|
6661
|
+
tsConfigFilePath
|
|
6662
|
+
};
|
|
6663
|
+
}
|
|
6664
|
+
/** Instantiates a ts-morph Project using the default typescript config and nearest tsconfig.json file */
|
|
6665
|
+
function buildTsMorphProject(projectDir) {
|
|
6666
|
+
process.chdir(projectDir);
|
|
6667
|
+
return new Project({
|
|
6668
|
+
tsConfigFilePath: path.join(projectDir, "tsconfig.json"),
|
|
6669
|
+
skipFileDependencyResolution: true
|
|
6670
|
+
});
|
|
6671
|
+
}
|
|
6672
|
+
//#endregion
|
|
6673
|
+
//#region src/utils/unsafe-utils.ts
|
|
6674
|
+
function getInitialStates(scopeState) {
|
|
6675
|
+
const { global, local } = scopeState;
|
|
6676
|
+
const scopes = {
|
|
6677
|
+
global,
|
|
6678
|
+
local
|
|
6679
|
+
};
|
|
6680
|
+
Object.entries(scopes).forEach(([scope, state]) => {
|
|
6681
|
+
if (!isEmptyStateSchema(state.schema) && state.initialValue === "") throw new Error(`${scope.charAt(0).toLocaleUpperCase() + scope.slice(1)} scope has a defined schema but is missing an initial value.`);
|
|
6682
|
+
});
|
|
6683
|
+
return {
|
|
6684
|
+
initialGlobalState: handleEmptyState(global.initialValue),
|
|
6685
|
+
initialLocalState: handleEmptyState(local.initialValue)
|
|
6686
|
+
};
|
|
6687
|
+
}
|
|
6688
|
+
function isEmptyStateSchema(schema) {
|
|
6689
|
+
return schema === "" || !schema.includes("{");
|
|
6690
|
+
}
|
|
6691
|
+
function handleEmptyState(state) {
|
|
6692
|
+
return state === "" ? "{}" : state;
|
|
6693
|
+
}
|
|
6694
|
+
//#endregion
|
|
6695
|
+
//#region src/utils/validation.ts
|
|
6696
|
+
/**
|
|
6697
|
+
* Validates that a DocumentModelGlobalState has all required properties for successful code generation.
|
|
6698
|
+
*
|
|
6699
|
+
* @param documentModelState - The DocumentModelGlobalState to validate
|
|
6700
|
+
* @returns Validation result with isValid flag and error messages
|
|
6701
|
+
*/
|
|
6702
|
+
function validateDocumentModelState(documentModelState) {
|
|
6703
|
+
const errors = [];
|
|
6704
|
+
if (!documentModelState.id || typeof documentModelState.id !== "string" || documentModelState.id.trim() === "") errors.push("Property \"id\" is required and must be a non-empty string");
|
|
6705
|
+
if (!documentModelState.name || typeof documentModelState.name !== "string" || documentModelState.name.trim() === "") errors.push("Property \"name\" is required and must be a non-empty string");
|
|
6706
|
+
if (typeof documentModelState.extension !== "string") errors.push("Property \"extension\" must be a string");
|
|
6707
|
+
if (!Array.isArray(documentModelState.specifications) || documentModelState.specifications.length === 0) {
|
|
6708
|
+
errors.push("Property \"specifications\" is required and must be a non-empty array");
|
|
6709
|
+
return {
|
|
6710
|
+
isValid: false,
|
|
6711
|
+
errors
|
|
6712
|
+
};
|
|
6713
|
+
}
|
|
6714
|
+
const latestSpec = documentModelState.specifications[documentModelState.specifications.length - 1];
|
|
6715
|
+
if (!latestSpec) {
|
|
6716
|
+
errors.push("Latest specification is missing or invalid");
|
|
6717
|
+
return {
|
|
6718
|
+
isValid: false,
|
|
6719
|
+
errors
|
|
6720
|
+
};
|
|
6721
|
+
}
|
|
6722
|
+
if (!latestSpec.state) {
|
|
6723
|
+
errors.push("Latest specification must have a \"state\" property");
|
|
6724
|
+
return {
|
|
6725
|
+
isValid: false,
|
|
6726
|
+
errors
|
|
6727
|
+
};
|
|
6728
|
+
}
|
|
6729
|
+
if (!latestSpec.state.global) errors.push("Latest specification state must have a \"global\" property");
|
|
6730
|
+
else {
|
|
6731
|
+
const globalState = latestSpec.state.global;
|
|
6732
|
+
if (typeof globalState.schema !== "string") errors.push("Global state \"schema\" must be a string");
|
|
6733
|
+
if (typeof globalState.initialValue !== "string") errors.push("Global state \"initialValue\" must be a string");
|
|
6734
|
+
if (globalState.schema && globalState.schema.trim() !== "" && globalState.schema.includes("{") && (!globalState.initialValue || globalState.initialValue.trim() === "")) errors.push("Global state has a defined schema but is missing an initial value");
|
|
6735
|
+
}
|
|
6736
|
+
if (!latestSpec.state.local) errors.push("Latest specification state must have a \"local\" property");
|
|
6737
|
+
else {
|
|
6738
|
+
const localState = latestSpec.state.local;
|
|
6739
|
+
if (typeof localState.schema !== "string") errors.push("Local state \"schema\" must be a string");
|
|
6740
|
+
if (typeof localState.initialValue !== "string") errors.push("Local state \"initialValue\" must be a string");
|
|
6741
|
+
if (localState.schema && localState.schema.trim() !== "" && localState.schema.includes("{") && (!localState.initialValue || localState.initialValue.trim() === "")) errors.push("Local state has a defined schema but is missing an initial value");
|
|
6742
|
+
}
|
|
6743
|
+
if (!Array.isArray(latestSpec.modules)) errors.push("Latest specification must have a \"modules\" array");
|
|
6744
|
+
else {
|
|
6745
|
+
if (latestSpec.modules.length === 0) errors.push("Latest specification must have at least one module defined");
|
|
6746
|
+
latestSpec.modules.forEach((module, moduleIndex) => {
|
|
6747
|
+
if (!module.name || typeof module.name !== "string" || module.name.trim() === "") errors.push(`Module at index ${moduleIndex} must have a non-empty "name" property`);
|
|
6748
|
+
if (!Array.isArray(module.operations)) errors.push(`Module "${module.name || `at index ${moduleIndex}`}" must have an "operations" array`);
|
|
6749
|
+
else {
|
|
6750
|
+
if (module.operations.length === 0) errors.push(`Module "${module.name || `at index ${moduleIndex}`}" must have at least one operation defined`);
|
|
6751
|
+
module.operations.forEach((operation, operationIndex) => {
|
|
6752
|
+
const operationId = operation.name || `at index ${operationIndex}`;
|
|
6753
|
+
const moduleId = module.name || `at index ${moduleIndex}`;
|
|
6754
|
+
if (!operation.name || typeof operation.name !== "string" || operation.name.trim() === "") errors.push(`Operation ${operationId} in module "${moduleId}" must have a non-empty "name" property`);
|
|
6755
|
+
if (operation.schema !== null && typeof operation.schema !== "string") errors.push(`Operation "${operationId}" in module "${moduleId}" must have a "schema" that is either null or a string`);
|
|
6756
|
+
if (operation.scope !== void 0 && typeof operation.scope !== "string") errors.push(`Operation "${operationId}" in module "${moduleId}" must have a "scope" that is a string if provided`);
|
|
6757
|
+
if (!Array.isArray(operation.errors)) errors.push(`Operation "${operationId}" in module "${moduleId}" must have an "errors" array`);
|
|
6758
|
+
});
|
|
6759
|
+
}
|
|
6760
|
+
});
|
|
6761
|
+
}
|
|
6762
|
+
return {
|
|
6763
|
+
isValid: errors.length === 0,
|
|
6764
|
+
errors
|
|
6765
|
+
};
|
|
6766
|
+
}
|
|
6767
|
+
//#endregion
|
|
6768
|
+
//#region src/file-builders/editor-common.ts
|
|
6769
|
+
/** Generates the `module.ts` file for a document editor or app */
|
|
6770
|
+
function makeEditorModuleFile({ project, editorDirPath, editorName, documentModelId, editorId, legacyMultipleDocumentTypes }) {
|
|
6771
|
+
if (documentModelId && !!legacyMultipleDocumentTypes) throw new Error("Cannot specify both documentModelId and legacyMultipleDocumentTypes");
|
|
6772
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(editorDirPath, "module.ts"));
|
|
6773
|
+
sourceFile.replaceWithText("");
|
|
6774
|
+
const template = documentEditorModuleFileTemplate({
|
|
6775
|
+
editorName,
|
|
6776
|
+
editorId,
|
|
6777
|
+
pascalCaseEditorName: pascalCase(editorName),
|
|
6778
|
+
documentTypes: documentModelId ? `["${documentModelId}"]` : JSON.stringify(legacyMultipleDocumentTypes)
|
|
6779
|
+
});
|
|
6780
|
+
sourceFile.replaceWithText(template);
|
|
6781
|
+
}
|
|
6782
|
+
async function makeEditorsFile(args) {
|
|
6783
|
+
const { project, editorsDirPath } = args;
|
|
6784
|
+
const sourceFile = project.createSourceFile(path.join(editorsDirPath, "editors.ts"), editorsTemplate, { overwrite: true });
|
|
6785
|
+
const editorsArray = sourceFile.getVariableDeclarationOrThrow("editors").getFirstDescendantByKindOrThrow(SyntaxKind.ArrayLiteralExpression);
|
|
6786
|
+
pipe(project.getDirectoryOrThrow(editorsDirPath).getDescendantSourceFiles(), filter((sourceFile) => sourceFile.getBaseName() === "module.ts"), uniqueBy((sourceFile) => sourceFile.getFilePath()), map((sourceFile) => getVariableDeclarationByTypeName(sourceFile, "EditorModule")), filter(isTruthy), map((variableDeclaration) => ({
|
|
6787
|
+
name: variableDeclaration.getName(),
|
|
6788
|
+
editorDir: variableDeclaration.getSourceFile().getDirectory().getBaseName()
|
|
6789
|
+
})), map(({ name, editorDir }) => ({
|
|
6790
|
+
name,
|
|
6791
|
+
namedImports: [name],
|
|
6792
|
+
moduleSpecifier: `./${path.join(editorDir, "module.js")}`
|
|
6793
|
+
})), forEach(({ name, namedImports, moduleSpecifier }) => {
|
|
6794
|
+
sourceFile.addImportDeclaration({
|
|
6795
|
+
namedImports,
|
|
6796
|
+
moduleSpecifier
|
|
6797
|
+
});
|
|
6798
|
+
editorsArray.addElement(name);
|
|
6799
|
+
}));
|
|
6800
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6801
|
+
}
|
|
6802
|
+
async function makeEditorsIndexFile(args) {
|
|
6803
|
+
const { project, editorsDirPath } = args;
|
|
6804
|
+
const sourceFile = project.createSourceFile(path.join(editorsDirPath, "index.ts"), "", { overwrite: true });
|
|
6805
|
+
pipe(project.getDirectoryOrThrow(editorsDirPath).getDescendantSourceFiles(), filter((sourceFile) => sourceFile.getBaseName() === "module.ts"), uniqueBy((sourceFile) => sourceFile.getFilePath()), map((sourceFile) => getVariableDeclarationByTypeName(sourceFile, "EditorModule")), filter(isTruthy), map((variableDeclaration) => ({
|
|
6806
|
+
name: variableDeclaration.getName(),
|
|
6807
|
+
editorDir: variableDeclaration.getSourceFile().getDirectory().getBaseName()
|
|
6808
|
+
})), map(({ name, editorDir }) => ({
|
|
6809
|
+
namedExports: [name],
|
|
6810
|
+
moduleSpecifier: `./${path.join(editorDir, "module.js")}`
|
|
6811
|
+
})), forEach(({ namedExports, moduleSpecifier }) => {
|
|
6812
|
+
sourceFile.addExportDeclaration({
|
|
6813
|
+
namedExports,
|
|
6814
|
+
moduleSpecifier
|
|
6815
|
+
});
|
|
6816
|
+
}));
|
|
6817
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6818
|
+
}
|
|
6819
|
+
//#endregion
|
|
6820
|
+
//#region src/file-builders/app.ts
|
|
6821
|
+
/** Generates a app with the configs for `allowedDocumentModelIds` and `isDragAndDropEnabled` */
|
|
6822
|
+
async function tsMorphGenerateApp({ project, editorDir, editorName, editorId, allowedDocumentModelIds, isDragAndDropEnabled }) {
|
|
6823
|
+
const { directory: editorsDir } = getOrCreateDirectory(project, "editors");
|
|
6824
|
+
const editorsDirPath = editorsDir.getPath();
|
|
6825
|
+
const { directory: documentModelsDir } = getOrCreateDirectory(project, "document-models");
|
|
6826
|
+
const documentModelsDirPath = documentModelsDir.getPath();
|
|
6827
|
+
const editorDirPath = path.join(editorsDirPath, editorDir);
|
|
6828
|
+
const projectDir = editorsDir.getParentOrThrow().getPath();
|
|
6829
|
+
const editorComponentsDirPath = path.join(editorDirPath, "components");
|
|
6830
|
+
await ensureDirectoriesExist(project, documentModelsDirPath, editorsDirPath, editorDirPath, editorComponentsDirPath);
|
|
6831
|
+
await makeNavigationBreadcrumbsFile({
|
|
6832
|
+
project,
|
|
6833
|
+
editorComponentsDirPath
|
|
6834
|
+
});
|
|
6835
|
+
await makeCreateDocumentFile({
|
|
6836
|
+
project,
|
|
6837
|
+
editorComponentsDirPath
|
|
6838
|
+
});
|
|
6839
|
+
await makeEmptyStateFile({
|
|
6840
|
+
project,
|
|
6841
|
+
editorComponentsDirPath
|
|
6842
|
+
});
|
|
6843
|
+
await makeFoldersFile({
|
|
6844
|
+
project,
|
|
6845
|
+
editorComponentsDirPath
|
|
6846
|
+
});
|
|
6847
|
+
await makeFolderTreeFile({
|
|
6848
|
+
project,
|
|
6849
|
+
editorComponentsDirPath
|
|
6850
|
+
});
|
|
6851
|
+
await makeFilesFile({
|
|
6852
|
+
project,
|
|
6853
|
+
editorComponentsDirPath
|
|
6854
|
+
});
|
|
6855
|
+
await makeDriveExplorerFile({
|
|
6856
|
+
project,
|
|
6857
|
+
editorComponentsDirPath
|
|
6858
|
+
});
|
|
6859
|
+
await makeDriveContentsFile({
|
|
6860
|
+
project,
|
|
6861
|
+
editorComponentsDirPath
|
|
6862
|
+
});
|
|
6863
|
+
await makeAppComponent({
|
|
6864
|
+
project,
|
|
6865
|
+
editorDirPath
|
|
6866
|
+
});
|
|
6867
|
+
await makeAppConfigFile({
|
|
6868
|
+
project,
|
|
6869
|
+
allowedDocumentModelIds,
|
|
6870
|
+
isDragAndDropEnabled,
|
|
6871
|
+
editorDirPath
|
|
6872
|
+
});
|
|
6873
|
+
makeEditorModuleFile({
|
|
6874
|
+
project,
|
|
6875
|
+
editorName,
|
|
6876
|
+
editorId,
|
|
6877
|
+
editorDirPath,
|
|
6878
|
+
documentModelId: "powerhouse/document-drive"
|
|
6879
|
+
});
|
|
6880
|
+
await makeEditorsFile({
|
|
6881
|
+
project,
|
|
6882
|
+
editorsDirPath
|
|
6883
|
+
});
|
|
6884
|
+
await makeEditorsIndexFile({
|
|
6885
|
+
project,
|
|
6886
|
+
editorsDirPath
|
|
6887
|
+
});
|
|
6888
|
+
await createOrUpdateManifest({ apps: [{
|
|
6889
|
+
name: editorName,
|
|
6890
|
+
id: editorId,
|
|
6891
|
+
documentTypes: ["powerhousedao/document-drive"]
|
|
6892
|
+
}] }, projectDir);
|
|
6893
|
+
}
|
|
6894
|
+
async function makeAppComponent({ project, editorDirPath }) {
|
|
6895
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorDirPath, "editor.tsx"));
|
|
6896
|
+
if (alreadyExists) {
|
|
6897
|
+
const editorFunction = sourceFile.getFunction("Editor");
|
|
6898
|
+
if (editorFunction) {
|
|
6899
|
+
if (!editorFunction.isDefaultExport()) editorFunction.setIsDefaultExport(true);
|
|
6900
|
+
return;
|
|
6901
|
+
}
|
|
6902
|
+
}
|
|
6903
|
+
const template = appEditorFileTemplate();
|
|
6904
|
+
sourceFile.replaceWithText(template);
|
|
6905
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6906
|
+
}
|
|
6907
|
+
async function makeAppConfigFile({ project, editorDirPath, allowedDocumentModelIds, isDragAndDropEnabled }) {
|
|
6908
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(editorDirPath, "config.ts"));
|
|
6909
|
+
const allowedDocumentTypesString = JSON.stringify(allowedDocumentModelIds);
|
|
6910
|
+
const template = appConfigFileTemplate({
|
|
6911
|
+
isDragAndDropEnabledString: isDragAndDropEnabled ? "true" : "false",
|
|
6912
|
+
allowedDocumentTypesString
|
|
6913
|
+
});
|
|
6914
|
+
sourceFile.replaceWithText(template);
|
|
6915
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6916
|
+
}
|
|
6917
|
+
async function makeDriveContentsFile({ project, editorComponentsDirPath }) {
|
|
6918
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorComponentsDirPath, "DriveContents.tsx"));
|
|
6919
|
+
if (alreadyExists) return;
|
|
6920
|
+
const template = appDriveContentsFileTemplate();
|
|
6921
|
+
sourceFile.replaceWithText(template);
|
|
6922
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6923
|
+
}
|
|
6924
|
+
async function makeNavigationBreadcrumbsFile({ project, editorComponentsDirPath }) {
|
|
6925
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorComponentsDirPath, "NavigationBreadcrumbs.tsx"));
|
|
6926
|
+
if (alreadyExists) return;
|
|
6927
|
+
sourceFile.replaceWithText(driveExplorerNavigationBreadcrumbsFileTemplate());
|
|
6928
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6929
|
+
}
|
|
6930
|
+
async function makeFoldersFile({ project, editorComponentsDirPath }) {
|
|
6931
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorComponentsDirPath, "Folders.tsx"));
|
|
6932
|
+
if (alreadyExists) return;
|
|
6933
|
+
const template = appFoldersFileTemplate();
|
|
6934
|
+
sourceFile.replaceWithText(template);
|
|
6935
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6936
|
+
}
|
|
6937
|
+
async function makeFilesFile({ project, editorComponentsDirPath }) {
|
|
6938
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorComponentsDirPath, "Files.tsx"));
|
|
6939
|
+
if (alreadyExists) return;
|
|
6940
|
+
const template = appFilesFileTemplate();
|
|
6941
|
+
sourceFile.replaceWithText(template);
|
|
6942
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6943
|
+
}
|
|
6944
|
+
async function makeDriveExplorerFile({ project, editorComponentsDirPath }) {
|
|
6945
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorComponentsDirPath, "DriveExplorer.tsx"));
|
|
6946
|
+
if (alreadyExists) return;
|
|
6947
|
+
sourceFile.replaceWithText(driveExplorerFileTemplate);
|
|
6948
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6949
|
+
}
|
|
6950
|
+
async function makeFolderTreeFile({ project, editorComponentsDirPath }) {
|
|
6951
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorComponentsDirPath, "FolderTree.tsx"));
|
|
6952
|
+
if (alreadyExists) return;
|
|
6953
|
+
sourceFile.replaceWithText(folderTreeFileTemplate);
|
|
6954
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6955
|
+
}
|
|
6956
|
+
async function makeEmptyStateFile({ project, editorComponentsDirPath }) {
|
|
6957
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorComponentsDirPath, "EmptyState.tsx"));
|
|
6958
|
+
if (alreadyExists) return;
|
|
6959
|
+
sourceFile.replaceWithText(emptyStateFileTemplate);
|
|
6960
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6961
|
+
}
|
|
6962
|
+
async function makeCreateDocumentFile({ project, editorComponentsDirPath }) {
|
|
6963
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorComponentsDirPath, "CreateDocument.tsx"));
|
|
6964
|
+
if (alreadyExists) return;
|
|
6965
|
+
sourceFile.replaceWithText(createDocumentFileTemplate);
|
|
6966
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6967
|
+
}
|
|
6968
|
+
//#endregion
|
|
6969
|
+
//#region src/file-builders/boilerplate/generated-project-files.ts
|
|
6970
|
+
async function writeGeneratedProjectRootFiles(projectDir) {
|
|
6971
|
+
await writeFileEnsuringDir(join(projectDir, "tsconfig.json"), await formatSafe(tsConfigTemplate, "json"));
|
|
6972
|
+
await writeFileEnsuringDir(join(projectDir, "index.html"), await formatSafe(indexHtmlTemplate, "html"));
|
|
6973
|
+
await writeFileEnsuringDir(join(projectDir, "main.tsx"), await formatSafe(mainTsxTemplate));
|
|
6974
|
+
await writeFileEnsuringDir(join(projectDir, "eslint.config.js"), await formatSafe(eslintConfigTemplate));
|
|
6975
|
+
await writeFileEnsuringDir(join(projectDir, "index.ts"), await formatSafe(indexTsTemplate));
|
|
6976
|
+
await writeFileEnsuringDir(join(projectDir, "style.css"), await formatSafe(styleTemplate, "css"));
|
|
6977
|
+
await writeFileEnsuringDir(join(projectDir, "vitest.config.ts"), await formatSafe(vitestConfigTemplate));
|
|
6978
|
+
}
|
|
6979
|
+
async function writeGeneratedDocumentModelsFiles(projectDir) {
|
|
6980
|
+
await writeFileEnsuringDir(join(projectDir, "document-models/document-models.ts"), await formatSafe(documentModelsTemplate));
|
|
6981
|
+
await writeFileEnsuringDir(join(projectDir, "document-models/index.ts"), await formatSafe(documentModelsIndexTemplate));
|
|
6982
|
+
await writeFileEnsuringDir(join(projectDir, "document-models/upgrade-manifests.ts"), await formatSafe(upgradeManifestsTemplate));
|
|
6983
|
+
}
|
|
6984
|
+
async function writeGeneratedEditorsFiles(projectDir) {
|
|
6985
|
+
await writeFileEnsuringDir(join(projectDir, "editors/editors.ts"), await formatSafe(editorsTemplate));
|
|
6986
|
+
await writeFileEnsuringDir(join(projectDir, "editors/index.ts"), await formatSafe(editorsIndexTemplate));
|
|
6987
|
+
}
|
|
6988
|
+
async function writeGeneratedProcessorsFiles(projectDir) {
|
|
6989
|
+
await writeFileEnsuringDir(join(projectDir, "processors/factory.ts"), await formatSafe(processorsFactoryTemplate));
|
|
6990
|
+
await writeFileEnsuringDir(join(projectDir, "processors/index.ts"), await formatSafe(processorsIndexTemplate));
|
|
6991
|
+
await writeFileEnsuringDir(join(projectDir, "processors/connect.ts"), await formatSafe(factoryBuildersTemplate));
|
|
6992
|
+
await writeFileEnsuringDir(join(projectDir, "processors/switchboard.ts"), await formatSafe(factoryBuildersTemplate));
|
|
6993
|
+
await writeFileEnsuringDir(join(projectDir, "processors/index.ts"), await formatSafe(processorsIndexTemplate));
|
|
6994
|
+
}
|
|
6995
|
+
async function writeGeneratedSubgraphsFiles(projectDir) {
|
|
6996
|
+
await writeFileEnsuringDir(join(projectDir, "subgraphs/index.ts"), await formatSafe(subgraphsIndexTemplate));
|
|
6997
|
+
}
|
|
6998
|
+
async function writeModuleFiles(projectDir = process.cwd()) {
|
|
6999
|
+
await writeGeneratedDocumentModelsFiles(projectDir);
|
|
7000
|
+
await writeGeneratedEditorsFiles(projectDir);
|
|
7001
|
+
await writeGeneratedProcessorsFiles(projectDir);
|
|
7002
|
+
await writeGeneratedSubgraphsFiles(projectDir);
|
|
7003
|
+
}
|
|
7004
|
+
async function writeAiConfigFiles(projectDir = process.cwd()) {
|
|
7005
|
+
await writeFileEnsuringDir(join(projectDir, "CLAUDE.md"), agentsTemplate);
|
|
7006
|
+
await writeFileEnsuringDir(join(projectDir, "AGENTS.md"), agentsTemplate);
|
|
7007
|
+
await writeFileEnsuringDir(join(projectDir, ".mcp.json"), mcpTemplate);
|
|
7008
|
+
await writeFileEnsuringDir(join(projectDir, ".gemini/settings.json"), geminiSettingsTemplate);
|
|
7009
|
+
await writeFileEnsuringDir(join(projectDir, ".cursor/mcp.json"), cursorMcpTemplate);
|
|
7010
|
+
await writeFileEnsuringDir(join(projectDir, ".claude/settings.local.json"), claudeSettingsLocalTemplate);
|
|
7011
|
+
}
|
|
7012
|
+
async function writeProjectRootFiles(args, projectDir = process.cwd()) {
|
|
7013
|
+
const { name, tag, version, remoteDrive } = args;
|
|
7014
|
+
await writeFileEnsuringDir("LICENSE", licenseTemplate);
|
|
7015
|
+
await writeFileEnsuringDir("README.md", readmeTemplate);
|
|
7016
|
+
await writeFileEnsuringDir(".npmrc", npmrcTemplate);
|
|
7017
|
+
const packageJson = await buildBoilerplatePackageJson({
|
|
7018
|
+
name,
|
|
7019
|
+
tag,
|
|
7020
|
+
version
|
|
7021
|
+
});
|
|
7022
|
+
await createOrUpdateManifest({ name }, projectDir);
|
|
7023
|
+
await writeFileEnsuringDir("powerhouse.config.json", await buildPowerhouseConfigTemplate({
|
|
7024
|
+
tag,
|
|
7025
|
+
version,
|
|
7026
|
+
remoteDrive
|
|
7027
|
+
}));
|
|
7028
|
+
await writeFileEnsuringDir("package.json", packageJson);
|
|
7029
|
+
}
|
|
7030
|
+
async function writeCIFiles(projectDir = process.cwd()) {
|
|
7031
|
+
await writeFileEnsuringDir(join(projectDir, ".github/workflows/sync-and-publish.yml"), syncAndPublishWorkflowTemplate);
|
|
7032
|
+
await writeFileEnsuringDir(join(projectDir, "Dockerfile"), dockerfileTemplate);
|
|
7033
|
+
await writeFileEnsuringDir(join(projectDir, "docker/nginx.conf"), nginxConfTemplate);
|
|
7034
|
+
await writeFileEnsuringDir(join(projectDir, "docker/connect-entrypoint.sh"), connectEntrypointTemplate);
|
|
7035
|
+
await writeFileEnsuringDir(join(projectDir, "docker/switchboard-entrypoint.sh"), switchboardEntrypointTemplate);
|
|
7036
|
+
}
|
|
7037
|
+
async function writeAllGeneratedProjectFiles(projectDir = process.cwd()) {
|
|
7038
|
+
await writeGeneratedProjectRootFiles(projectDir);
|
|
7039
|
+
await writeModuleFiles(projectDir);
|
|
7040
|
+
await writeAiConfigFiles(projectDir);
|
|
7041
|
+
await writeCIFiles(projectDir);
|
|
7042
|
+
}
|
|
7043
|
+
//#endregion
|
|
7044
|
+
//#region src/file-builders/boilerplate/package.json.ts
|
|
7045
|
+
async function buildBoilerplatePackageJson(args) {
|
|
7046
|
+
const { name, tag, version, workspace } = args;
|
|
7047
|
+
return packageJsonTemplate(name, await makeVersionedDependencies({
|
|
7048
|
+
names: VERSIONED_DEPENDENCIES,
|
|
7049
|
+
tag,
|
|
7050
|
+
version
|
|
7051
|
+
}), await makeVersionedDependencies({
|
|
7052
|
+
names: VERSIONED_DEV_DEPENDENCIES,
|
|
7053
|
+
tag,
|
|
7054
|
+
version
|
|
7055
|
+
}));
|
|
7056
|
+
}
|
|
7057
|
+
//#endregion
|
|
7058
|
+
//#region src/file-builders/clis/generate-cli-docs.ts
|
|
7059
|
+
function getCommandHelpInfo(entry) {
|
|
7060
|
+
return {
|
|
7061
|
+
name: entry.name,
|
|
7062
|
+
description: entry.command.description ?? "",
|
|
7063
|
+
helpTopics: entry.command.helpTopics?.() ?? []
|
|
7064
|
+
};
|
|
7065
|
+
}
|
|
7066
|
+
function getCommandsHelpInfo(entries) {
|
|
7067
|
+
return entries.map(getCommandHelpInfo);
|
|
7068
|
+
}
|
|
7069
|
+
function makeCliDocsFromHelp(args) {
|
|
7070
|
+
const { cliDescription, docsIntroduction, docsTitle, entries } = args;
|
|
7071
|
+
return stripVTControlCharacters(docsFromCliHelpTemplate({
|
|
7072
|
+
cliDescription,
|
|
7073
|
+
docsIntroduction,
|
|
7074
|
+
docsTitle,
|
|
7075
|
+
commandsHelpInfo: getCommandsHelpInfo(entries)
|
|
7076
|
+
}));
|
|
7077
|
+
}
|
|
7078
|
+
async function writeCliDocsMarkdownFile(args) {
|
|
7079
|
+
const { filePath, ...restArgs } = args;
|
|
7080
|
+
await writeFile(filePath, makeCliDocsFromHelp(restArgs), { encoding: "utf-8" });
|
|
7081
|
+
}
|
|
7082
|
+
//#endregion
|
|
7083
|
+
//#region src/file-builders/constants.ts
|
|
7084
|
+
const exportPaths = [
|
|
7085
|
+
"document-models",
|
|
7086
|
+
"editors",
|
|
7087
|
+
"subgraphs",
|
|
7088
|
+
"processors"
|
|
7089
|
+
];
|
|
7090
|
+
const rootExportPaths = { ".": {
|
|
7091
|
+
types: "./dist/index.d.ts",
|
|
7092
|
+
browser: "./dist/browser/index.js",
|
|
7093
|
+
node: "./dist/node/index.mjs"
|
|
7094
|
+
} };
|
|
7095
|
+
const nonStandardExportPaths = {
|
|
7096
|
+
"./manifest": "./dist/powerhouse.manifest.json",
|
|
7097
|
+
"./style.css": "./dist/style.css"
|
|
6374
7098
|
};
|
|
6375
|
-
|
|
7099
|
+
const packageScripts = {
|
|
7100
|
+
"test:watch": "vitest",
|
|
7101
|
+
lint: "eslint --config eslint.config.js --cache",
|
|
7102
|
+
"lint:fix": "npm run lint -- --fix",
|
|
7103
|
+
tsc: "tsc",
|
|
7104
|
+
"tsc:watch": "tsc --watch",
|
|
7105
|
+
generate: "ph-cli generate",
|
|
7106
|
+
connect: "ph-cli connect",
|
|
7107
|
+
build: "ph-cli build",
|
|
7108
|
+
reactor: "ph-cli reactor",
|
|
7109
|
+
service: "ph-cli service",
|
|
7110
|
+
vetra: "ph-cli vetra",
|
|
7111
|
+
"service-startup": "bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-startup.sh",
|
|
7112
|
+
"service-unstartup": "bash ./node_modules/@powerhousedao/ph-cli/dist/scripts/service-unstartup.sh"
|
|
7113
|
+
};
|
|
7114
|
+
const externalDependencies = {
|
|
7115
|
+
"@powerhousedao/document-engineering": "1.40.1",
|
|
7116
|
+
graphql: "^16.10.0",
|
|
7117
|
+
"graphql-tag": "^2.12.6",
|
|
7118
|
+
zod: "^4.3.5",
|
|
7119
|
+
react: "^19.2.3",
|
|
7120
|
+
"react-dom": "^19.2.3"
|
|
7121
|
+
};
|
|
7122
|
+
const externalDevDependencies = {
|
|
7123
|
+
"@eslint/js": "^9.38.0",
|
|
7124
|
+
"@tailwindcss/cli": "^4.1.18",
|
|
7125
|
+
"@types/node": "^24.9.2",
|
|
7126
|
+
"@types/react": "^19.2.3",
|
|
7127
|
+
eslint: "^9.38.0",
|
|
7128
|
+
"eslint-plugin-react": "^7.37.5",
|
|
7129
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
7130
|
+
"eslint-config-prettier": "^10.1.8",
|
|
7131
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
7132
|
+
globals: "^16.4.0",
|
|
7133
|
+
tailwindcss: "^4.1.16",
|
|
7134
|
+
typescript: "^5.9.3",
|
|
7135
|
+
"typescript-eslint": "^8.46.2",
|
|
7136
|
+
vitest: "4.1.1",
|
|
7137
|
+
"@vitejs/plugin-react": "6.0.1",
|
|
7138
|
+
"vite-tsconfig-paths": "6.1.1"
|
|
6376
7139
|
};
|
|
6377
|
-
|
|
6378
|
-
|
|
7140
|
+
const defaultManifest = {
|
|
7141
|
+
name: "",
|
|
7142
|
+
description: "",
|
|
7143
|
+
category: "",
|
|
7144
|
+
publisher: {
|
|
7145
|
+
name: "",
|
|
7146
|
+
url: ""
|
|
7147
|
+
},
|
|
7148
|
+
documentModels: [],
|
|
7149
|
+
editors: [],
|
|
7150
|
+
apps: [],
|
|
7151
|
+
subgraphs: [],
|
|
7152
|
+
processors: []
|
|
7153
|
+
};
|
|
7154
|
+
//#endregion
|
|
7155
|
+
//#region src/file-builders/document-editor.ts
|
|
7156
|
+
/** Generates a document editor for the given `documentModelId` (also called `documentType`) */
|
|
7157
|
+
async function tsMorphGenerateDocumentEditor({ project, editorDir, editorName, editorId, documentModelId }) {
|
|
7158
|
+
const { directory: documentModelsDir } = getOrCreateDirectory(project, "document-models");
|
|
7159
|
+
const documentModelsDirPath = documentModelsDir.getPath();
|
|
7160
|
+
const { directory: editorsDir } = getOrCreateDirectory(project, "editors");
|
|
7161
|
+
const editorsDirPath = editorsDir.getPath();
|
|
7162
|
+
const projectDir = editorsDir.getParentOrThrow().getPath();
|
|
7163
|
+
const editorDirPath = path.join(editorsDirPath, editorDir);
|
|
7164
|
+
await ensureDirectoriesExist(project, documentModelsDirPath, editorsDirPath, editorDirPath, path.join(editorDirPath, "components"));
|
|
7165
|
+
const documentTypeMetadata = getDocumentTypeMetadata({
|
|
7166
|
+
project,
|
|
7167
|
+
documentModelId
|
|
7168
|
+
});
|
|
7169
|
+
const editorVariableNames = getEditorVariableNames(documentTypeMetadata);
|
|
7170
|
+
await makeEditorComponent({
|
|
7171
|
+
project,
|
|
7172
|
+
editorDirPath,
|
|
7173
|
+
...documentTypeMetadata,
|
|
7174
|
+
...editorVariableNames
|
|
7175
|
+
});
|
|
7176
|
+
makeEditorModuleFile({
|
|
7177
|
+
project,
|
|
7178
|
+
editorName,
|
|
7179
|
+
editorId,
|
|
7180
|
+
documentModelId,
|
|
7181
|
+
editorDirPath
|
|
7182
|
+
});
|
|
7183
|
+
await makeEditorsFile({
|
|
7184
|
+
project,
|
|
7185
|
+
editorsDirPath
|
|
7186
|
+
});
|
|
7187
|
+
await makeEditorsIndexFile({
|
|
7188
|
+
project,
|
|
7189
|
+
editorsDirPath
|
|
7190
|
+
});
|
|
7191
|
+
await createOrUpdateManifest({ editors: [{
|
|
7192
|
+
name: editorName,
|
|
7193
|
+
id: editorId,
|
|
7194
|
+
documentTypes: [documentTypeMetadata.documentModelId]
|
|
7195
|
+
}] }, projectDir);
|
|
7196
|
+
}
|
|
7197
|
+
async function makeEditorComponent(args) {
|
|
7198
|
+
const { project, editorDirPath } = args;
|
|
7199
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(editorDirPath, "editor.tsx"));
|
|
7200
|
+
if (alreadyExists) {
|
|
7201
|
+
const functionDeclaration = sourceFile.getFunction("Editor");
|
|
7202
|
+
if (functionDeclaration) {
|
|
7203
|
+
if (!functionDeclaration.isDefaultExport()) functionDeclaration.setIsDefaultExport(true);
|
|
7204
|
+
return;
|
|
7205
|
+
}
|
|
7206
|
+
}
|
|
7207
|
+
const template = documentEditorEditorFileTemplate(args);
|
|
7208
|
+
sourceFile.replaceWithText(template);
|
|
7209
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7210
|
+
}
|
|
7211
|
+
//#endregion
|
|
7212
|
+
//#region src/codegen/graphql.ts
|
|
7213
|
+
const scalars = {
|
|
7214
|
+
Unknown: "unknown",
|
|
7215
|
+
DateTime: "string",
|
|
7216
|
+
Attachment: "string",
|
|
7217
|
+
Address: "`${string}:0x${string}`",
|
|
7218
|
+
...generatorTypeDefs
|
|
7219
|
+
};
|
|
7220
|
+
const scalarsValidation = {
|
|
7221
|
+
Unknown: "z.unknown()",
|
|
7222
|
+
DateTime: "z.string().datetime()",
|
|
7223
|
+
Attachment: "z.string()",
|
|
7224
|
+
Address: "z.custom<`${string}:0x${string}`>((val) => /^[a-zA-Z0-9]+:0x[a-fA-F0-9]{40}$/.test(val as string))",
|
|
7225
|
+
...validationSchema
|
|
7226
|
+
};
|
|
7227
|
+
const avoidOptionals = {
|
|
7228
|
+
field: true,
|
|
7229
|
+
inputValue: false
|
|
7230
|
+
};
|
|
7231
|
+
const maybeValue = "T | null | undefined";
|
|
7232
|
+
const typescriptConfig = {
|
|
7233
|
+
avoidOptionals,
|
|
7234
|
+
scalars,
|
|
7235
|
+
strictScalars: true,
|
|
7236
|
+
enumsAsTypes: true,
|
|
7237
|
+
skipTypename: true,
|
|
7238
|
+
maybeValue
|
|
7239
|
+
};
|
|
7240
|
+
const validationSchemaConfig = {
|
|
7241
|
+
avoidOptionals,
|
|
7242
|
+
scalars,
|
|
7243
|
+
strictScalars: true,
|
|
7244
|
+
enumsAsTypes: true,
|
|
7245
|
+
skipTypename: true,
|
|
7246
|
+
importFrom: `./types.js`,
|
|
7247
|
+
schema: "zodv4",
|
|
7248
|
+
useTypeImports: true,
|
|
7249
|
+
scalarSchemas: scalarsValidation,
|
|
7250
|
+
directives: { equals: { value: ["regex", "/^$1$/"] } },
|
|
7251
|
+
withObjectType: true,
|
|
7252
|
+
maybeValue
|
|
7253
|
+
};
|
|
7254
|
+
function buildSchemasForModules(modules) {
|
|
7255
|
+
const schemaStrings = [];
|
|
7256
|
+
for (const module of modules) {
|
|
7257
|
+
schemaStrings.push(`# ${module.name}`);
|
|
7258
|
+
const operationsSchemas = module.operations.map((operation) => operation.schema).filter((schema) => schema !== null);
|
|
7259
|
+
schemaStrings.push(...operationsSchemas);
|
|
7260
|
+
}
|
|
7261
|
+
return schemaStrings;
|
|
7262
|
+
}
|
|
7263
|
+
function buildGraphqlDocumentStringForSpecification(specification) {
|
|
7264
|
+
const customScalarSchemas = Object.keys(scalars).map((k) => `scalar ${k}`).join("\n");
|
|
7265
|
+
const stateSchemas = Object.values(specification.state).map((state) => state.schema);
|
|
7266
|
+
const moduleSchemas = buildSchemasForModules(specification.modules);
|
|
7267
|
+
return [
|
|
7268
|
+
customScalarSchemas,
|
|
7269
|
+
...stateSchemas,
|
|
7270
|
+
...moduleSchemas
|
|
7271
|
+
];
|
|
7272
|
+
}
|
|
7273
|
+
async function formatContentWithPrettier(path, content) {
|
|
7274
|
+
return await format(content, { parser: "typescript" });
|
|
7275
|
+
}
|
|
7276
|
+
async function generateTypesAndZodSchemasFromGraphql(args) {
|
|
7277
|
+
const { schemaDirPath, schema } = args;
|
|
7278
|
+
await generate({
|
|
7279
|
+
overwrite: true,
|
|
7280
|
+
watch: false,
|
|
7281
|
+
hooks: { beforeOneFileWrite: formatContentWithPrettier },
|
|
7282
|
+
generates: {
|
|
7283
|
+
[`${schemaDirPath}/types.ts`]: {
|
|
7284
|
+
schema,
|
|
7285
|
+
config: typescriptConfig,
|
|
7286
|
+
plugins: [{ typescript: typescriptConfig }]
|
|
7287
|
+
},
|
|
7288
|
+
[`${schemaDirPath}/zod.ts`]: {
|
|
7289
|
+
schema,
|
|
7290
|
+
config: validationSchemaConfig,
|
|
7291
|
+
plugins: [{ add: { content: "/* eslint-disable @typescript-eslint/no-empty-object-type */" } }, { "graphql-codegen-typescript-validation-schema": validationSchemaConfig }]
|
|
7292
|
+
}
|
|
7293
|
+
}
|
|
7294
|
+
}, true);
|
|
7295
|
+
}
|
|
7296
|
+
async function generateDocumentModelZodSchemas(args) {
|
|
7297
|
+
const { specification, schemaDirPath, versionDirPath } = args;
|
|
7298
|
+
const schema = buildGraphqlDocumentStringForSpecification(specification).filter(Boolean).join("\n\n");
|
|
7299
|
+
await generateTypesAndZodSchemasFromGraphql({
|
|
7300
|
+
schemaDirPath,
|
|
7301
|
+
schema
|
|
7302
|
+
});
|
|
7303
|
+
await fs.writeFile(path$1.join(versionDirPath, "schema.graphql"), schema);
|
|
7304
|
+
}
|
|
7305
|
+
//#endregion
|
|
7306
|
+
//#region src/file-builders/document-model/gen-dir.ts
|
|
7307
|
+
async function makeDocumentModelGenDirOperationModulesFiles(fileMakerArgs) {
|
|
7308
|
+
for (const module of fileMakerArgs.specification.modules) await makeGenDirOperationModuleFiles({
|
|
7309
|
+
...fileMakerArgs,
|
|
7310
|
+
module
|
|
7311
|
+
});
|
|
7312
|
+
}
|
|
7313
|
+
async function makeGenDirOperationModuleFiles(fileMakerArgs) {
|
|
7314
|
+
await makeOperationModuleGenActionsFile(fileMakerArgs);
|
|
7315
|
+
await makeOperationModuleGenCreatorsFile(fileMakerArgs);
|
|
7316
|
+
await makeOperationModuleGenOperationsFile(fileMakerArgs);
|
|
7317
|
+
await makeOperationModuleGenErrorFile(fileMakerArgs);
|
|
7318
|
+
}
|
|
7319
|
+
async function makeDocumentModelGenUtilsFile(args) {
|
|
7320
|
+
const template = documentModelGenUtilsTemplate(args);
|
|
7321
|
+
const { project, genDirPath } = args;
|
|
7322
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "utils.ts"));
|
|
7323
|
+
sourceFile.replaceWithText(template);
|
|
7324
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7325
|
+
}
|
|
7326
|
+
async function makeDocumentModelDocumentTypeFile(args) {
|
|
7327
|
+
const template = documentModelDocumentTypeTemplate(args);
|
|
7328
|
+
const { project, genDirPath } = args;
|
|
7329
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "document-type.ts"));
|
|
7330
|
+
sourceFile.replaceWithText(template);
|
|
7331
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7332
|
+
}
|
|
7333
|
+
async function makeDocumentModelSchemaIndexFile(args) {
|
|
7334
|
+
const template = documentModelSchemaIndexTemplate;
|
|
7335
|
+
const { project, schemaDirPath } = args;
|
|
7336
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(schemaDirPath, "index.ts"));
|
|
7337
|
+
sourceFile.replaceWithText(template);
|
|
7338
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7339
|
+
}
|
|
7340
|
+
async function makeDocumentModelGenTypesFile(args) {
|
|
7341
|
+
const template = documentModelGenTypesTemplate(args);
|
|
7342
|
+
const { project, genDirPath } = args;
|
|
7343
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "types.ts"));
|
|
7344
|
+
sourceFile.replaceWithText(template);
|
|
7345
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7346
|
+
}
|
|
7347
|
+
async function makeDocumentModelGenDocumentModelFile(args) {
|
|
7348
|
+
const { project, genDirPath, documentModelState } = args;
|
|
7349
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "document-model.ts"));
|
|
7350
|
+
sourceFile.replaceWithText("");
|
|
7351
|
+
sourceFile.addImportDeclaration({
|
|
7352
|
+
namedImports: ["DocumentModelGlobalState"],
|
|
7353
|
+
moduleSpecifier: "document-model",
|
|
7354
|
+
isTypeOnly: true
|
|
7355
|
+
});
|
|
7356
|
+
const documentModelStateString = buildObjectLiteral(documentModelState, sourceFile);
|
|
7357
|
+
sourceFile.addVariableStatement({
|
|
7358
|
+
declarationKind: VariableDeclarationKind.Const,
|
|
7359
|
+
isExported: true,
|
|
7360
|
+
declarations: [{
|
|
7361
|
+
name: "documentModel",
|
|
7362
|
+
type: "DocumentModelGlobalState",
|
|
7363
|
+
initializer: documentModelStateString
|
|
7364
|
+
}]
|
|
7365
|
+
});
|
|
7366
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7367
|
+
}
|
|
7368
|
+
async function makeDocumentModelGenDocumentSchemaFile(args) {
|
|
7369
|
+
const template = documentModelDocumentSchemaFileTemplate(args);
|
|
7370
|
+
const { project, genDirPath } = args;
|
|
7371
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "document-schema.ts"));
|
|
7372
|
+
sourceFile.replaceWithText(template);
|
|
7373
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7374
|
+
}
|
|
7375
|
+
async function makeDocumentModelGenCreatorsFile(args) {
|
|
7376
|
+
const template = documentModelGenCreatorsFileTemplate(args);
|
|
7377
|
+
const { project, genDirPath } = args;
|
|
7378
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "creators.ts"));
|
|
7379
|
+
sourceFile.replaceWithText(template);
|
|
7380
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7381
|
+
}
|
|
7382
|
+
async function makeDocumentModelGenPhFactoriesFile(args) {
|
|
7383
|
+
const template = documentModelPhFactoriesFileTemplate(args);
|
|
7384
|
+
const { project, genDirPath } = args;
|
|
7385
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "ph-factories.ts"));
|
|
7386
|
+
sourceFile.replaceWithText(template);
|
|
7387
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7388
|
+
}
|
|
7389
|
+
async function makeDocumentModelGenControllerFile(args) {
|
|
7390
|
+
const template = documentModelGenControllerFileTemplate(args);
|
|
7391
|
+
const { project, genDirPath } = args;
|
|
7392
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "controller.ts"));
|
|
7393
|
+
sourceFile.replaceWithText(template);
|
|
7394
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7395
|
+
}
|
|
7396
|
+
async function makeDocumentModelGenIndexFile(args) {
|
|
7397
|
+
const template = documentModelGenIndexFileTemplate(args);
|
|
7398
|
+
const { project, genDirPath } = args;
|
|
7399
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "index.ts"));
|
|
7400
|
+
sourceFile.replaceWithText(template);
|
|
7401
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7402
|
+
}
|
|
7403
|
+
async function makeDocumentModelGenActionsFile(args) {
|
|
7404
|
+
const template = documentModelGenActionsFileTemplate(args);
|
|
7405
|
+
const { project, genDirPath } = args;
|
|
7406
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "actions.ts"));
|
|
7407
|
+
sourceFile.replaceWithText(template);
|
|
7408
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7409
|
+
}
|
|
7410
|
+
async function makeDocumentModelGenReducerFile(args) {
|
|
7411
|
+
const template = documentModelGenReducerFileTemplate(args);
|
|
7412
|
+
const { project, genDirPath } = args;
|
|
7413
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(genDirPath, "reducer.ts"));
|
|
7414
|
+
sourceFile.replaceWithText(template);
|
|
7415
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7416
|
+
}
|
|
7417
|
+
async function makeOperationModuleGenActionsFile(args) {
|
|
7418
|
+
const { module } = args;
|
|
7419
|
+
const kebabCaseModuleName = kebabCase(module.name);
|
|
7420
|
+
const template = documentModelOperationModuleActionsFileTemplate(args);
|
|
7421
|
+
const { project, genDirPath } = args;
|
|
7422
|
+
const dirPath = path.join(genDirPath, kebabCaseModuleName);
|
|
7423
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(dirPath, "actions.ts"));
|
|
7424
|
+
sourceFile.replaceWithText(template);
|
|
7425
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7426
|
+
}
|
|
7427
|
+
async function makeOperationModuleGenCreatorsFile(args) {
|
|
7428
|
+
const { module } = args;
|
|
7429
|
+
const kebabCaseModuleName = kebabCase(module.name);
|
|
7430
|
+
const template = documentModelOperationsModuleCreatorsFileTemplate(args);
|
|
7431
|
+
const { project, genDirPath } = args;
|
|
7432
|
+
const dirPath = path.join(genDirPath, kebabCaseModuleName);
|
|
7433
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(dirPath, "creators.ts"));
|
|
7434
|
+
sourceFile.replaceWithText(template);
|
|
7435
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7436
|
+
}
|
|
7437
|
+
async function makeOperationModuleGenOperationsFile(args) {
|
|
7438
|
+
const { module } = args;
|
|
7439
|
+
const kebabCaseModuleName = kebabCase(module.name);
|
|
7440
|
+
const template = documentModelOperationsModuleOperationsFileTemplate(args);
|
|
7441
|
+
const { project, genDirPath } = args;
|
|
7442
|
+
const dirPath = path.join(genDirPath, kebabCaseModuleName);
|
|
7443
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(dirPath, "operations.ts"));
|
|
7444
|
+
sourceFile.replaceWithText(template);
|
|
7445
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7446
|
+
}
|
|
7447
|
+
async function makeOperationModuleGenErrorFile(args) {
|
|
7448
|
+
const { module } = args;
|
|
7449
|
+
const kebabCaseModuleName = kebabCase(module.name);
|
|
7450
|
+
const template = documentModelOperationsModuleErrorFileTemplate(args);
|
|
7451
|
+
const { project, genDirPath } = args;
|
|
7452
|
+
const dirPath = path.join(genDirPath, kebabCaseModuleName);
|
|
7453
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(dirPath, "error.ts"));
|
|
7454
|
+
sourceFile.replaceWithText(template);
|
|
7455
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7456
|
+
}
|
|
7457
|
+
//#endregion
|
|
7458
|
+
//#region src/file-builders/document-model/root-dir.ts
|
|
7459
|
+
async function makeDocumentModelVersionIndexFile(args) {
|
|
7460
|
+
const template = documentModelIndexTemplate;
|
|
7461
|
+
const { project, versionDirPath } = args;
|
|
7462
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(versionDirPath, "index.ts"));
|
|
7463
|
+
sourceFile.replaceWithText(template);
|
|
7464
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7465
|
+
}
|
|
7466
|
+
async function makeDocumentModelUtilsFile(args) {
|
|
7467
|
+
const template = documentModelUtilsTemplate(args);
|
|
7468
|
+
const { project, versionDirPath } = args;
|
|
7469
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(versionDirPath, "utils.ts"));
|
|
7470
|
+
sourceFile.replaceWithText(template);
|
|
7471
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7472
|
+
}
|
|
7473
|
+
async function makeDocumentModelRootActionsFile(args) {
|
|
7474
|
+
const template = documentModelRootActionsFileTemplate(args);
|
|
7475
|
+
const { project, versionDirPath } = args;
|
|
7476
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(versionDirPath, "actions.ts"));
|
|
7477
|
+
sourceFile.replaceWithText(template);
|
|
7478
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7479
|
+
}
|
|
7480
|
+
async function makeDocumentModelHooksFile(args) {
|
|
7481
|
+
const template = documentModelHooksFileTemplate(args);
|
|
7482
|
+
const { project, versionDirPath } = args;
|
|
7483
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(versionDirPath, "hooks.ts"));
|
|
7484
|
+
sourceFile.replaceWithText(template);
|
|
7485
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7486
|
+
}
|
|
7487
|
+
async function makeDocumentModelModuleFile(args) {
|
|
7488
|
+
const { project, versionDirPath } = args;
|
|
7489
|
+
const template = documentModelModuleFileTemplate(args);
|
|
7490
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(versionDirPath, "module.ts"));
|
|
7491
|
+
sourceFile.replaceWithText(template);
|
|
7492
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7493
|
+
}
|
|
7494
|
+
//#endregion
|
|
7495
|
+
//#region src/file-builders/document-model/src-dir.ts
|
|
7496
|
+
async function makeReducerOperationHandlersForModules(fileMakerArgs) {
|
|
7497
|
+
const { specification } = fileMakerArgs;
|
|
7498
|
+
for (const module of specification.modules) await makeReducerOperationHandlerForModule({
|
|
7499
|
+
...fileMakerArgs,
|
|
7500
|
+
module
|
|
7501
|
+
});
|
|
7502
|
+
}
|
|
7503
|
+
async function makeReducerOperationHandlerForModule({ project, module, version, srcDirPath, versionImportPath, pascalCaseDocumentType, camelCaseDocumentType }) {
|
|
7504
|
+
const kebabCaseModuleName = kebabCase(module.name);
|
|
7505
|
+
const pascalCaseModuleName = pascalCase(module.name);
|
|
7506
|
+
const filePath = path.join(srcDirPath, "reducers", `${kebabCaseModuleName}.ts`);
|
|
7507
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, filePath);
|
|
7508
|
+
if (!alreadyExists) {
|
|
7509
|
+
const previousVersionFile = getPreviousVersionSourceFile({
|
|
7510
|
+
project,
|
|
7511
|
+
version,
|
|
7512
|
+
filePath
|
|
7513
|
+
});
|
|
7514
|
+
if (previousVersionFile) sourceFile.replaceWithText(previousVersionFile.getText());
|
|
7515
|
+
}
|
|
7516
|
+
const operationsInterfaceTypeName = `${pascalCaseDocumentType}${pascalCaseModuleName}Operations`;
|
|
7517
|
+
const operationsInterfaceVariableName = `${camelCaseDocumentType}${pascalCaseModuleName}Operations`;
|
|
7518
|
+
const existingOperationsInterfaceTypeImport = sourceFile.getImportDeclaration((importDeclaration) => !!importDeclaration.getNamedImports().find((importSpecifier) => importSpecifier.getName() === operationsInterfaceTypeName));
|
|
7519
|
+
if (existingOperationsInterfaceTypeImport) existingOperationsInterfaceTypeImport.remove();
|
|
7520
|
+
const operationsInterfaceTypeProperties = sourceFile.addImportDeclaration({
|
|
7521
|
+
namedImports: [operationsInterfaceTypeName],
|
|
7522
|
+
moduleSpecifier: versionImportPath,
|
|
7523
|
+
isTypeOnly: true
|
|
7524
|
+
}).getNamedImports().find((value) => value.getName() === operationsInterfaceTypeName)?.getNameNode().getType().getProperties().map((symbol) => symbol.getName());
|
|
7525
|
+
if (!operationsInterfaceTypeProperties) throw new Error("Failed to create operation handler object");
|
|
7526
|
+
let operationsInterfaceVariableStatement = sourceFile.getVariableStatement(operationsInterfaceVariableName);
|
|
7527
|
+
if (!operationsInterfaceVariableStatement) operationsInterfaceVariableStatement = sourceFile.addVariableStatement({
|
|
7528
|
+
declarationKind: VariableDeclarationKind.Const,
|
|
7529
|
+
isExported: true,
|
|
7530
|
+
declarations: [{
|
|
7531
|
+
name: operationsInterfaceVariableName,
|
|
7532
|
+
type: operationsInterfaceTypeName,
|
|
7533
|
+
initializer: "{}"
|
|
7534
|
+
}]
|
|
7535
|
+
});
|
|
7536
|
+
const operationsInterfaceObject = getObjectLiteral(operationsInterfaceVariableStatement);
|
|
7537
|
+
if (!operationsInterfaceObject) throw new Error("Failed to build reducer object");
|
|
7538
|
+
const operationsByMethodName = /* @__PURE__ */ new Map();
|
|
7539
|
+
for (const operation of module.operations) if (operation.name) {
|
|
7540
|
+
const methodName = `${camelCase(operation.name)}Operation`;
|
|
7541
|
+
operationsByMethodName.set(methodName, operation);
|
|
7542
|
+
}
|
|
7543
|
+
for (const name of operationsInterfaceTypeProperties) {
|
|
7544
|
+
if (operationsInterfaceObject.getProperty(name)) continue;
|
|
7545
|
+
const reducerCode = operationsByMethodName.get(name)?.reducer?.trim();
|
|
7546
|
+
operationsInterfaceObject.addMethod({
|
|
7547
|
+
name,
|
|
7548
|
+
parameters: [{ name: "state" }, { name: "action" }],
|
|
7549
|
+
statements: reducerCode ? [reducerCode] : [`// TODO: implement ${name} reducer`, ts$1`throw new Error("Reducer for '${name}' not implemented.")`.raw]
|
|
7550
|
+
});
|
|
7551
|
+
}
|
|
7552
|
+
addErrorImportsForModule(sourceFile, module);
|
|
7553
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7554
|
+
}
|
|
7555
|
+
async function makeDocumentModelSrcIndexFile({ project, ...variableNames }) {
|
|
7556
|
+
const template = documentModelSrcIndexFileTemplate;
|
|
7557
|
+
const { srcDirPath } = variableNames;
|
|
7558
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(srcDirPath, "index.ts"));
|
|
7559
|
+
sourceFile.replaceWithText(template);
|
|
7560
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7561
|
+
}
|
|
7562
|
+
async function makeDocumentModelSrcUtilsFile({ project, srcDirPath, version }) {
|
|
7563
|
+
const template = documentModelSrcUtilsTemplate;
|
|
7564
|
+
const filePath = path.join(srcDirPath, "utils.ts");
|
|
7565
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, filePath);
|
|
7566
|
+
if (!alreadyExists) {
|
|
7567
|
+
const previousVersionSourceFile = getPreviousVersionSourceFile({
|
|
7568
|
+
project,
|
|
7569
|
+
version,
|
|
7570
|
+
filePath
|
|
7571
|
+
});
|
|
7572
|
+
if (previousVersionSourceFile) sourceFile.replaceWithText(previousVersionSourceFile.getText());
|
|
7573
|
+
else sourceFile.replaceWithText(template);
|
|
7574
|
+
}
|
|
7575
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7576
|
+
}
|
|
7577
|
+
function addErrorImportsForModule(sourceFile, module) {
|
|
7578
|
+
const allErrors = [];
|
|
7579
|
+
for (const operation of module.operations) if (Array.isArray(operation.errors)) {
|
|
7580
|
+
for (const error of operation.errors) if (error.name && !allErrors.find((e) => e.name === error.name)) allErrors.push({ name: error.name });
|
|
7581
|
+
}
|
|
7582
|
+
if (allErrors.length === 0) return;
|
|
7583
|
+
const sourceFileContent = sourceFile.getFullText();
|
|
7584
|
+
const usedErrors = [];
|
|
7585
|
+
for (const error of allErrors) if (new RegExp(`\\b${error.name}\\b`, "g").test(sourceFileContent)) usedErrors.push(error.name);
|
|
7586
|
+
if (usedErrors.length === 0) return;
|
|
7587
|
+
const errorImportPath = `../../gen/${kebabCase(module.name)}/error.js`;
|
|
7588
|
+
const existingErrorImport = sourceFile.getImportDeclarations().find((importDecl) => importDecl.getModuleSpecifierValue() === errorImportPath);
|
|
7589
|
+
if (existingErrorImport) {
|
|
7590
|
+
const existingNamedImports = existingErrorImport.getNamedImports().map((namedImport) => namedImport.getName());
|
|
7591
|
+
const newErrorsToImport = usedErrors.filter((errorName) => !existingNamedImports.includes(errorName));
|
|
7592
|
+
if (newErrorsToImport.length > 0) existingErrorImport.addNamedImports(newErrorsToImport);
|
|
7593
|
+
} else sourceFile.addImportDeclaration({
|
|
7594
|
+
namedImports: usedErrors,
|
|
7595
|
+
moduleSpecifier: errorImportPath
|
|
7596
|
+
});
|
|
7597
|
+
}
|
|
7598
|
+
//#endregion
|
|
7599
|
+
//#region src/file-builders/document-model/tests-dir.ts
|
|
7600
|
+
async function makeDocumentModelModulesOperationTestFiles(fileMakerArgs) {
|
|
7601
|
+
for (const module of fileMakerArgs.specification.modules) await makeOperationModuleTestFile({
|
|
7602
|
+
...fileMakerArgs,
|
|
7603
|
+
module
|
|
7604
|
+
});
|
|
7605
|
+
}
|
|
7606
|
+
async function makeOperationModuleTestFile(args) {
|
|
7607
|
+
const { project, module, version, versionImportPath, testsDirPath, isPhDocumentOfTypeFunctionName } = args;
|
|
7608
|
+
const kebabCaseModuleName = kebabCase(module.name);
|
|
7609
|
+
const moduleOperationsTypeName = `${pascalCase(module.name)}Operations`;
|
|
7610
|
+
const filePath = path.join(testsDirPath, `${kebabCaseModuleName}.test.ts`);
|
|
7611
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, filePath);
|
|
7612
|
+
if (!alreadyExists) {
|
|
7613
|
+
const previousVersionSourceFile = getPreviousVersionSourceFile({
|
|
7614
|
+
project,
|
|
7615
|
+
version,
|
|
7616
|
+
filePath
|
|
7617
|
+
});
|
|
7618
|
+
if (previousVersionSourceFile) sourceFile.replaceWithText(previousVersionSourceFile.getText());
|
|
7619
|
+
else sourceFile.replaceWithText(ts$1`
|
|
7620
|
+
import { generateMock } from "document-model";
|
|
7621
|
+
import { describe, expect, it } from "vitest";
|
|
7622
|
+
|
|
7623
|
+
describe("${moduleOperationsTypeName}", () => {
|
|
7624
|
+
|
|
7625
|
+
});
|
|
7626
|
+
`.raw);
|
|
7627
|
+
}
|
|
7628
|
+
const importNames = makeOperationImportNames(args);
|
|
7629
|
+
const namedImports = importNames.map((name) => ({ name }));
|
|
7630
|
+
let actionsImportDeclaration = sourceFile.getImportDeclarations().filter((i) => !i.isTypeOnly()).find((importDeclaration) => importDeclaration.getModuleSpecifier().getText().includes(versionImportPath));
|
|
7631
|
+
if (!actionsImportDeclaration) actionsImportDeclaration = sourceFile.addImportDeclaration({
|
|
7632
|
+
namedImports,
|
|
7633
|
+
moduleSpecifier: versionImportPath
|
|
7634
|
+
});
|
|
7635
|
+
else {
|
|
7636
|
+
actionsImportDeclaration.setModuleSpecifier(versionImportPath);
|
|
7637
|
+
const existingNamedImports = actionsImportDeclaration.getNamedImports().map((value) => value.getName());
|
|
7638
|
+
for (const name of importNames) if (!existingNamedImports.includes(name)) actionsImportDeclaration.addNamedImport(name);
|
|
7639
|
+
}
|
|
7640
|
+
const describeCall = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).find((call) => {
|
|
7641
|
+
const expressionText = call.getExpression().getText();
|
|
7642
|
+
const firstArg = call.getArguments()[0];
|
|
7643
|
+
return expressionText === "describe" && pascalCase(firstArg.getText()).includes(moduleOperationsTypeName);
|
|
7644
|
+
});
|
|
7645
|
+
if (!describeCall) {
|
|
7646
|
+
console.error(`Test file at path ${filePath} has no describe block for ${moduleOperationsTypeName}`);
|
|
7647
|
+
return;
|
|
7648
|
+
}
|
|
7649
|
+
const describeCallBody = describeCall.getArguments()[1].asKindOrThrow(SyntaxKind.ArrowFunction);
|
|
7650
|
+
const testCaseNames = describeCall.getDescendantsOfKind(SyntaxKind.CallExpression).filter((call) => {
|
|
7651
|
+
const expressionText = call.getExpression().getText();
|
|
7652
|
+
return expressionText === "it" || expressionText === "test";
|
|
7653
|
+
}).map((c) => c.getArguments()[0].getText());
|
|
7654
|
+
const testCasesToAdd = pipe(module.operations, filter((o) => !isIncludedIn(camelCase(o.name ?? ""), testCaseNames)), map((o) => makeTestCaseForOperation(o, isPhDocumentOfTypeFunctionName)));
|
|
7655
|
+
describeCallBody.addStatements(testCasesToAdd);
|
|
7656
|
+
const GENERATE_MOCK_NAME = "generateMock";
|
|
7657
|
+
const GENERATE_MOCK_MODULE_SPECIFIER = "@powerhousedao/codegen";
|
|
7658
|
+
const generateMockImport = sourceFile.getImportDeclaration((i) => i.getNamedImports().some((v) => v.getText().includes(GENERATE_MOCK_NAME)));
|
|
7659
|
+
if (sourceFile.getText().includes(GENERATE_MOCK_NAME) && !generateMockImport) sourceFile.addImportDeclaration({
|
|
7660
|
+
namedImports: [GENERATE_MOCK_NAME],
|
|
7661
|
+
moduleSpecifier: GENERATE_MOCK_MODULE_SPECIFIER
|
|
7662
|
+
});
|
|
7663
|
+
sourceFile.fixUnusedIdentifiers();
|
|
7664
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7665
|
+
}
|
|
7666
|
+
async function makeDocumentModelTestFile(args) {
|
|
7667
|
+
const { project, testsDirPath } = args;
|
|
7668
|
+
const template = documentModelTestFileTemplate(args);
|
|
7669
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(testsDirPath, "document-model.test.ts"));
|
|
7670
|
+
if (alreadyExists) return;
|
|
7671
|
+
sourceFile.replaceWithText(template);
|
|
7672
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7673
|
+
}
|
|
7674
|
+
//#endregion
|
|
7675
|
+
//#region src/file-builders/document-model/upgrades-dir.ts
|
|
7676
|
+
async function makeUpgradeFile(args) {
|
|
7677
|
+
const { project, version, upgradesDirPath } = args;
|
|
7678
|
+
if (version < 2) return;
|
|
7679
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(upgradesDirPath, `v${version}.ts`));
|
|
7680
|
+
if (alreadyExists) return;
|
|
7681
|
+
const template = upgradeTransitionTemplate(args);
|
|
7682
|
+
sourceFile.replaceWithText(template);
|
|
7683
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7684
|
+
}
|
|
7685
|
+
async function createOrUpdateUpgradeManifestFile(args) {
|
|
7686
|
+
const { project, versions, upgradesDirPath } = args;
|
|
7687
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(upgradesDirPath, "upgrade-manifest.ts"));
|
|
7688
|
+
const template = upgradeManifestTemplate(args);
|
|
7689
|
+
sourceFile.replaceWithText(template);
|
|
7690
|
+
const upgradeTransitionImports = buildUpgradeTransitionImports(versions);
|
|
7691
|
+
sourceFile.addImportDeclarations(upgradeTransitionImports);
|
|
7692
|
+
const upgradeManifestStatement = getVariableDeclarationByTypeName(sourceFile, "UpgradeManifest")?.getVariableStatementOrThrow();
|
|
7693
|
+
const upgradesProperty = getObjectLiteral(upgradeManifestStatement)?.getProperty("upgrades");
|
|
7694
|
+
const upgrades = buildUpgrades(versions);
|
|
7695
|
+
upgradesProperty?.replaceWithText(upgrades);
|
|
7696
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7697
|
+
}
|
|
7698
|
+
function buildUpgrades(specVersions) {
|
|
7699
|
+
const upgradeStrings = [];
|
|
7700
|
+
for (const version of specVersions) {
|
|
7701
|
+
if (version < 2) continue;
|
|
7702
|
+
upgradeStrings.push(`v${version}`);
|
|
7703
|
+
}
|
|
7704
|
+
return `upgrades: { ${upgradeStrings.join(",\n")} }`;
|
|
7705
|
+
}
|
|
7706
|
+
function buildUpgradeTransitionImports(specVersions) {
|
|
7707
|
+
const imports = [];
|
|
7708
|
+
for (const version of specVersions) {
|
|
7709
|
+
if (version < 2) continue;
|
|
7710
|
+
const namedImports = [`v${version}`];
|
|
7711
|
+
const moduleSpecifier = `./v${version}.js`;
|
|
7712
|
+
imports.push({
|
|
7713
|
+
namedImports,
|
|
7714
|
+
moduleSpecifier
|
|
7715
|
+
});
|
|
7716
|
+
}
|
|
7717
|
+
return imports;
|
|
7718
|
+
}
|
|
7719
|
+
async function createOrUpdateVersionConstantsFile({ versions, latestVersion, project, upgradesDirPath }) {
|
|
7720
|
+
const SUPPORTED_VERSIONS = "supportedVersions";
|
|
7721
|
+
const LATEST_VERSION = "latestVersion";
|
|
7722
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(upgradesDirPath, "versions.ts"));
|
|
7723
|
+
sourceFile.replaceWithText("");
|
|
7724
|
+
const latestVersionIndex = versions.indexOf(latestVersion);
|
|
7725
|
+
const versionInitializer = `[${versions.join(", ")}] as const;`;
|
|
7726
|
+
const latestInitializer = `${SUPPORTED_VERSIONS}[${latestVersionIndex}];`;
|
|
7727
|
+
sourceFile.addVariableStatement({
|
|
7728
|
+
declarationKind: VariableDeclarationKind.Const,
|
|
7729
|
+
isExported: true,
|
|
7730
|
+
declarations: [{
|
|
7731
|
+
name: SUPPORTED_VERSIONS,
|
|
7732
|
+
initializer: versionInitializer
|
|
7733
|
+
}]
|
|
7734
|
+
});
|
|
7735
|
+
sourceFile.addVariableStatement({
|
|
7736
|
+
declarationKind: VariableDeclarationKind.Const,
|
|
7737
|
+
isExported: true,
|
|
7738
|
+
declarations: [{
|
|
7739
|
+
name: LATEST_VERSION,
|
|
7740
|
+
initializer: latestInitializer
|
|
7741
|
+
}]
|
|
7742
|
+
});
|
|
7743
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7744
|
+
}
|
|
7745
|
+
async function makeUpgradesIndexFile({ project, upgradesDirPath, versions, upgradeManifestName }) {
|
|
7746
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(upgradesDirPath, "index.ts"));
|
|
7747
|
+
sourceFile.replaceWithText("");
|
|
7748
|
+
const upgradeReducerExports = makeUpgradeReducerExports(versions);
|
|
7749
|
+
sourceFile.addExportDeclarations([
|
|
7750
|
+
{
|
|
7751
|
+
namedExports: [upgradeManifestName],
|
|
7752
|
+
moduleSpecifier: "./upgrade-manifest.js"
|
|
7753
|
+
},
|
|
7754
|
+
{
|
|
7755
|
+
namedExports: ["supportedVersions", "latestVersion"],
|
|
7756
|
+
moduleSpecifier: "./versions.js"
|
|
7757
|
+
},
|
|
7758
|
+
...upgradeReducerExports
|
|
7759
|
+
]);
|
|
7760
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7761
|
+
}
|
|
7762
|
+
function makeUpgradeReducerExports(specVersions) {
|
|
7763
|
+
const exports = [];
|
|
7764
|
+
for (const version of specVersions) {
|
|
7765
|
+
if (version < 2) continue;
|
|
7766
|
+
const namedExports = [`v${version}`];
|
|
7767
|
+
const moduleSpecifier = `./v${version}.js`;
|
|
7768
|
+
exports.push({
|
|
7769
|
+
namedExports,
|
|
7770
|
+
moduleSpecifier
|
|
7771
|
+
});
|
|
7772
|
+
}
|
|
7773
|
+
return exports;
|
|
7774
|
+
}
|
|
7775
|
+
//#endregion
|
|
7776
|
+
//#region src/file-builders/document-model/document-model.ts
|
|
7777
|
+
/** Generates a document model from the given `documentModelState`
|
|
7778
|
+
*
|
|
7779
|
+
* for each `specification` in the `documentModelState`
|
|
7780
|
+
*/
|
|
7781
|
+
async function tsMorphGenerateDocumentModel(documentModelState, project) {
|
|
7782
|
+
const { name, id, specifications } = documentModelState;
|
|
7783
|
+
const { directory: documentModelsDir } = getOrCreateDirectory(project, "document-models");
|
|
7784
|
+
const documentModelsDirPath = documentModelsDir.getPath();
|
|
7785
|
+
const projectDir = documentModelsDir.getParentOrThrow().getPath();
|
|
7786
|
+
const documentModelDirName = kebabCase(name);
|
|
7787
|
+
const documentModelDirPath = join$1(documentModelsDirPath, documentModelDirName);
|
|
7788
|
+
const documentModelImportPath = join$1("document-models", documentModelDirName);
|
|
7789
|
+
const upgradesDirPath = join$1(documentModelDirPath, "upgrades");
|
|
7790
|
+
const documentModelVariableNames = getDocumentModelVariableNames(name);
|
|
7791
|
+
await ensureDirectoriesExist(project, documentModelsDirPath, documentModelDirPath, upgradesDirPath);
|
|
7792
|
+
const versions = pipe(specifications, map(prop("version")), unique(), sort(subtract));
|
|
7793
|
+
if (versions.length !== specifications.length) throw new Error("Document model specifications array is misconfigured. Length does not match with spec versions.");
|
|
7794
|
+
const latestVersion = Math.max(...versions);
|
|
7795
|
+
if (prop(last(specifications), "version") !== latestVersion) throw new Error("Document model has incorrect version at the latest version index");
|
|
7796
|
+
await writeDocumentModelStateJsonFile({
|
|
7797
|
+
documentModelState,
|
|
7798
|
+
documentModelDirName,
|
|
7799
|
+
documentModelDirPath
|
|
7800
|
+
});
|
|
7801
|
+
for (const specification of specifications) {
|
|
7802
|
+
const { version } = specification;
|
|
7803
|
+
const versionDirName = `v${version}`;
|
|
7804
|
+
const versionDirPath = join$1(documentModelDirPath, versionDirName);
|
|
7805
|
+
const versionImportPath = join$1(documentModelImportPath, versionDirName);
|
|
7806
|
+
const srcDirPath = join$1(versionDirPath, "src");
|
|
7807
|
+
const testsDirPath = join$1(versionDirPath, "tests");
|
|
7808
|
+
const genDirPath = join$1(versionDirPath, "gen");
|
|
7809
|
+
const schemaDirPath = join$1(genDirPath, "schema");
|
|
7810
|
+
const { initialGlobalState, initialLocalState } = getInitialStates(specification.state);
|
|
7811
|
+
const hasLocalSchema = specification.state.local.schema !== "";
|
|
7812
|
+
const fileMakerArgs = {
|
|
7813
|
+
...documentModelVariableNames,
|
|
7814
|
+
project,
|
|
7815
|
+
documentModelState,
|
|
7816
|
+
version,
|
|
7817
|
+
versions,
|
|
7818
|
+
latestVersion,
|
|
7819
|
+
specification,
|
|
7820
|
+
initialGlobalState,
|
|
7821
|
+
initialLocalState,
|
|
7822
|
+
hasLocalSchema,
|
|
7823
|
+
projectDir,
|
|
7824
|
+
documentModelsDirPath,
|
|
7825
|
+
documentModelDirPath,
|
|
7826
|
+
documentModelDirName,
|
|
7827
|
+
documentModelImportPath,
|
|
7828
|
+
versionDirPath,
|
|
7829
|
+
versionDirName,
|
|
7830
|
+
versionImportPath,
|
|
7831
|
+
genDirPath,
|
|
7832
|
+
schemaDirPath,
|
|
7833
|
+
srcDirPath,
|
|
7834
|
+
testsDirPath,
|
|
7835
|
+
upgradesDirPath
|
|
7836
|
+
};
|
|
7837
|
+
await generateDocumentModelZodSchemas(fileMakerArgs);
|
|
7838
|
+
await makeDocumentModelVersionIndexFile(fileMakerArgs);
|
|
7839
|
+
await makeDocumentModelRootActionsFile(fileMakerArgs);
|
|
7840
|
+
await makeDocumentModelUtilsFile(fileMakerArgs);
|
|
7841
|
+
await makeDocumentModelHooksFile(fileMakerArgs);
|
|
7842
|
+
await makeDocumentModelModuleFile(fileMakerArgs);
|
|
7843
|
+
await makeDocumentModelSchemaIndexFile(fileMakerArgs);
|
|
7844
|
+
await makeDocumentModelGenUtilsFile(fileMakerArgs);
|
|
7845
|
+
await makeDocumentModelGenTypesFile(fileMakerArgs);
|
|
7846
|
+
await makeDocumentModelGenCreatorsFile(fileMakerArgs);
|
|
7847
|
+
await makeDocumentModelGenActionsFile(fileMakerArgs);
|
|
7848
|
+
await makeDocumentModelGenDocumentSchemaFile(fileMakerArgs);
|
|
7849
|
+
await makeDocumentModelGenReducerFile(fileMakerArgs);
|
|
7850
|
+
await makeDocumentModelDocumentTypeFile(fileMakerArgs);
|
|
7851
|
+
await makeDocumentModelGenIndexFile(fileMakerArgs);
|
|
7852
|
+
await makeDocumentModelGenDocumentModelFile(fileMakerArgs);
|
|
7853
|
+
await makeDocumentModelGenPhFactoriesFile(fileMakerArgs);
|
|
7854
|
+
await makeDocumentModelGenControllerFile(fileMakerArgs);
|
|
7855
|
+
await makeDocumentModelGenDirOperationModulesFiles(fileMakerArgs);
|
|
7856
|
+
await makeDocumentModelSrcIndexFile(fileMakerArgs);
|
|
7857
|
+
await makeDocumentModelSrcUtilsFile(fileMakerArgs);
|
|
7858
|
+
await makeReducerOperationHandlersForModules(fileMakerArgs);
|
|
7859
|
+
await makeDocumentModelTestFile(fileMakerArgs);
|
|
7860
|
+
await makeDocumentModelModulesOperationTestFiles(fileMakerArgs);
|
|
7861
|
+
await persistCustomFilesFromPreviousVersion(fileMakerArgs);
|
|
7862
|
+
await makeUpgradeFile(fileMakerArgs);
|
|
7863
|
+
await createOrUpdateUpgradeManifestFile(fileMakerArgs);
|
|
7864
|
+
}
|
|
7865
|
+
await createOrUpdateVersionConstantsFile({
|
|
7866
|
+
project,
|
|
7867
|
+
versions,
|
|
7868
|
+
latestVersion,
|
|
7869
|
+
upgradesDirPath
|
|
7870
|
+
});
|
|
7871
|
+
await makeUpgradesIndexFile({
|
|
7872
|
+
...documentModelVariableNames,
|
|
7873
|
+
project,
|
|
7874
|
+
versions,
|
|
7875
|
+
upgradesDirPath
|
|
7876
|
+
});
|
|
7877
|
+
await makeDocumentModelIndexFile({
|
|
7878
|
+
project,
|
|
7879
|
+
documentModelDirPath,
|
|
7880
|
+
latestVersion
|
|
7881
|
+
});
|
|
7882
|
+
await makeDocumentModelsFile({
|
|
7883
|
+
project,
|
|
7884
|
+
documentModelsDirPath
|
|
7885
|
+
});
|
|
7886
|
+
await makeDocumentModelsIndexFile({
|
|
7887
|
+
project,
|
|
7888
|
+
documentModelsDirPath
|
|
7889
|
+
});
|
|
7890
|
+
await makeUpgradeManifestsFile({
|
|
7891
|
+
project,
|
|
7892
|
+
documentModelsDirPath
|
|
7893
|
+
});
|
|
7894
|
+
await createOrUpdateManifest({ documentModels: [{
|
|
7895
|
+
name,
|
|
7896
|
+
id
|
|
7897
|
+
}] }, projectDir);
|
|
7898
|
+
}
|
|
7899
|
+
async function makeUpgradeManifestsFile(args) {
|
|
7900
|
+
const { project, documentModelsDirPath } = args;
|
|
7901
|
+
const sourceFile = project.createSourceFile(join$1(documentModelsDirPath, "upgrade-manifests.ts"), upgradeManifestsTemplate, { overwrite: true });
|
|
7902
|
+
const upgradeManifestsArray = sourceFile.getVariableDeclarationOrThrow("upgradeManifests").getFirstDescendantByKindOrThrow(SyntaxKind.ArrayLiteralExpression);
|
|
7903
|
+
pipe(project.getSourceFiles(), filter((sourceFile) => sourceFile.getBaseName() === "upgrade-manifest.ts"), map((sourceFile) => getVariableDeclarationByTypeName(sourceFile, "UpgradeManifest")), filter(isTruthy), map((variableDeclaration) => ({
|
|
7904
|
+
name: variableDeclaration.getName(),
|
|
7905
|
+
documentModelDir: variableDeclaration.getSourceFile().getDirectory().getParentOrThrow().getBaseName()
|
|
7906
|
+
})), uniqueBy(prop("name")), map(({ name, documentModelDir }) => ({
|
|
7907
|
+
name,
|
|
7908
|
+
namedImports: [name],
|
|
7909
|
+
moduleSpecifier: join$1("document-models", documentModelDir, "upgrades")
|
|
7910
|
+
})), forEach(({ name, namedImports, moduleSpecifier }) => {
|
|
7911
|
+
sourceFile.addImportDeclaration({
|
|
7912
|
+
namedImports,
|
|
7913
|
+
moduleSpecifier
|
|
7914
|
+
});
|
|
7915
|
+
upgradeManifestsArray.addElement(name);
|
|
7916
|
+
}));
|
|
7917
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7918
|
+
}
|
|
7919
|
+
async function makeDocumentModelsFile(args) {
|
|
7920
|
+
const { project, documentModelsDirPath } = args;
|
|
7921
|
+
const sourceFile = project.createSourceFile(join$1(documentModelsDirPath, "document-models.ts"), documentModelsTemplate, { overwrite: true });
|
|
7922
|
+
const documentModelsArray = sourceFile.getVariableDeclarationOrThrow("documentModels").getFirstDescendantByKindOrThrow(SyntaxKind.ArrayLiteralExpression);
|
|
7923
|
+
pipe(project.getDirectoryOrThrow(documentModelsDirPath).getDescendantSourceFiles(), filter((sourceFile) => sourceFile.getBaseName() === "module.ts"), uniqueBy((sourceFile) => sourceFile.getFilePath()), map((sourceFile) => getVariableDeclarationByTypeName(sourceFile, "DocumentModel")), filter(isTruthy), map((variableDeclaration) => ({
|
|
7924
|
+
name: variableDeclaration.getName(),
|
|
7925
|
+
directory: variableDeclaration.getSourceFile().getDirectory()
|
|
7926
|
+
})), map(({ name, directory }) => ({
|
|
7927
|
+
name,
|
|
7928
|
+
version: directory.getBaseName(),
|
|
7929
|
+
documentModelDir: directory.getParentOrThrow().getBaseName()
|
|
7930
|
+
})), filter(({ version }) => /^v\d+$/.test(version)), map(({ name, version, documentModelDir }) => ({
|
|
7931
|
+
name: `${name}${capitalize(version)}`,
|
|
7932
|
+
namedImports: [`${name} as ${name}${capitalize(version)}`],
|
|
7933
|
+
moduleSpecifier: join$1("document-models", documentModelDir, version)
|
|
7934
|
+
})), forEach(({ name, namedImports, moduleSpecifier }) => {
|
|
7935
|
+
sourceFile.addImportDeclaration({
|
|
7936
|
+
namedImports,
|
|
7937
|
+
moduleSpecifier
|
|
7938
|
+
});
|
|
7939
|
+
documentModelsArray.addElement(name);
|
|
7940
|
+
}));
|
|
7941
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7942
|
+
}
|
|
7943
|
+
async function makeDocumentModelsIndexFile(args) {
|
|
7944
|
+
const { project, documentModelsDirPath } = args;
|
|
7945
|
+
const sourceFile = project.createSourceFile(join$1(documentModelsDirPath, "index.ts"), "", { overwrite: true });
|
|
7946
|
+
pipe(project.getDirectoryOrThrow(documentModelsDirPath).getDescendantSourceFiles(), filter((sourceFile) => sourceFile.getBaseName() === "module.ts"), uniqueBy((sourceFile) => sourceFile.getFilePath()), map((sourceFile) => getVariableDeclarationByTypeName(sourceFile, "DocumentModel")), filter(isTruthy), map((variableDeclaration) => ({
|
|
7947
|
+
name: variableDeclaration.getName(),
|
|
7948
|
+
directory: variableDeclaration.getSourceFile().getDirectory()
|
|
7949
|
+
})), map(({ name, directory }) => ({
|
|
7950
|
+
name,
|
|
7951
|
+
version: directory.getBaseName(),
|
|
7952
|
+
documentModelDir: directory.getParentOrThrow().getBaseName()
|
|
7953
|
+
})), filter(({ version }) => /^v\d+$/.test(version)), map(({ name, version, documentModelDir }) => ({
|
|
7954
|
+
namedExports: [`${name} as ${name}${capitalize(version)}`],
|
|
7955
|
+
moduleSpecifier: `./${documentModelDir}/${version}/module.js`
|
|
7956
|
+
})), forEach(({ namedExports, moduleSpecifier }) => {
|
|
7957
|
+
sourceFile.addExportDeclaration({
|
|
7958
|
+
namedExports,
|
|
7959
|
+
moduleSpecifier
|
|
7960
|
+
});
|
|
7961
|
+
}));
|
|
7962
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7963
|
+
}
|
|
7964
|
+
/** Writes a json file derived from a `documentModelState` */
|
|
7965
|
+
async function writeDocumentModelStateJsonFile({ documentModelState, documentModelDirName, documentModelDirPath }) {
|
|
7966
|
+
await writeFile(join$1(documentModelDirPath, `${documentModelDirName}.json`), JSON.stringify(documentModelState, null, 2));
|
|
7967
|
+
}
|
|
7968
|
+
async function makeDocumentModelIndexFile(args) {
|
|
7969
|
+
const { project, documentModelDirPath, latestVersion } = args;
|
|
7970
|
+
const { sourceFile } = getOrCreateSourceFile(project, join$1(documentModelDirPath, "index.ts"));
|
|
7971
|
+
sourceFile.replaceWithText("");
|
|
7972
|
+
sourceFile.addExportDeclarations([{ moduleSpecifier: `./v${latestVersion}/index.js` }, { moduleSpecifier: `./upgrades/index.js` }]);
|
|
7973
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
7974
|
+
}
|
|
7975
|
+
async function persistCustomFilesFromPreviousVersion(args) {
|
|
7976
|
+
const { version, documentModelDirPath } = args;
|
|
7977
|
+
const previousVersion = version - 1;
|
|
7978
|
+
if (previousVersion <= 1) return;
|
|
7979
|
+
const currentVersionDirName = `v${version}`;
|
|
7980
|
+
const previousVersionDirName = `v${previousVersion}`;
|
|
7981
|
+
if (currentVersionDirName === previousVersionDirName) return;
|
|
7982
|
+
const previousVersionDirPath = join$1(documentModelDirPath, previousVersionDirName);
|
|
7983
|
+
const currentVersionDirPath = join$1(documentModelDirPath, currentVersionDirName);
|
|
7984
|
+
if (!await directoryExists(previousVersionDirPath)) return;
|
|
7985
|
+
const previousVersionFiles = (await readdir(previousVersionDirPath, {
|
|
7986
|
+
withFileTypes: true,
|
|
7987
|
+
recursive: true
|
|
7988
|
+
})).filter((dirEnt) => dirEnt.isFile()).map(({ name, parentPath }) => ({
|
|
7989
|
+
name,
|
|
7990
|
+
parentPath,
|
|
7991
|
+
relativePath: relative(previousVersionDirPath, parentPath)
|
|
7992
|
+
}));
|
|
7993
|
+
for (const { name, relativePath } of previousVersionFiles) {
|
|
7994
|
+
const filePathInCurrentVersionDir = join$1(currentVersionDirPath, relativePath, name);
|
|
7995
|
+
const filePathInPreviousVersionDir = join$1(previousVersionDirPath, relativePath, name);
|
|
7996
|
+
const existsInPreviousVersionDir = await fileExists(filePathInPreviousVersionDir);
|
|
7997
|
+
const existsInCurrentVersionDir = await fileExists(filePathInCurrentVersionDir);
|
|
7998
|
+
if (existsInPreviousVersionDir && !existsInCurrentVersionDir) {
|
|
7999
|
+
console.log(`Persisting file "${join$1(relativePath, name)}" from previous version directory.`);
|
|
8000
|
+
await mkdir(join$1(currentVersionDirPath, relativePath), { recursive: true });
|
|
8001
|
+
await copyFile(filePathInPreviousVersionDir, filePathInCurrentVersionDir);
|
|
8002
|
+
}
|
|
8003
|
+
}
|
|
8004
|
+
}
|
|
8005
|
+
//#endregion
|
|
8006
|
+
//#region src/file-builders/document-model/utils.ts
|
|
8007
|
+
function operationHasInput(operation) {
|
|
8008
|
+
return isNonNullish(operation.schema);
|
|
8009
|
+
}
|
|
8010
|
+
function operationHasEmptyInput(operation) {
|
|
8011
|
+
return operation.schema?.includes("_empty") && !operation.schema.replace(/_empty:\s*Boolean/, "").match(/\w+:\s*\w+/);
|
|
8012
|
+
}
|
|
8013
|
+
function operationHasAttachment(operation) {
|
|
8014
|
+
return operation.schema?.includes(": Attachment");
|
|
8015
|
+
}
|
|
8016
|
+
//#endregion
|
|
8017
|
+
//#region src/file-builders/index-files.ts
|
|
8018
|
+
/**
|
|
8019
|
+
* Makes a index.ts file for the modules file which exports the modules as individual exports instead of an array of named exports.
|
|
8020
|
+
*/
|
|
8021
|
+
function makeModulesIndexFile({ project, modulesDirPath, modules }) {
|
|
8022
|
+
const indexSourceFilePath = path$1.join(modulesDirPath, "index.ts");
|
|
8023
|
+
let indexSourceFile = project.getSourceFile(indexSourceFilePath);
|
|
8024
|
+
if (!indexSourceFile) indexSourceFile = project.createSourceFile(indexSourceFilePath, "");
|
|
8025
|
+
else indexSourceFile.replaceWithText("");
|
|
8026
|
+
indexSourceFile.addExportDeclarations(modules.map(({ versionedName, unversionedName, moduleSpecifier }) => ({
|
|
8027
|
+
namedExports: [versionedName ? `${unversionedName} as ${versionedName}` : unversionedName],
|
|
8028
|
+
moduleSpecifier
|
|
8029
|
+
})));
|
|
8030
|
+
}
|
|
8031
|
+
//#endregion
|
|
8032
|
+
//#region src/file-builders/manifest.ts
|
|
8033
|
+
async function getOrCreateManifestFile(manifestPath) {
|
|
8034
|
+
if (!await fileExists(manifestPath)) await writeJsonFile(manifestPath, defaultManifest);
|
|
8035
|
+
const manifestFile = await loadJsonFile(manifestPath);
|
|
8036
|
+
return ManifestSchema.parse(manifestFile);
|
|
8037
|
+
}
|
|
8038
|
+
function makeUpdatedModulesList(oldModules = [], newModules = []) {
|
|
8039
|
+
return pipe(concat(oldModules, newModules), uniqueBy(prop("id")));
|
|
8040
|
+
}
|
|
8041
|
+
function makeUpdatedConfig(oldConfig = [], newConfig = []) {
|
|
8042
|
+
return pipe(oldConfig, filter(({ name }) => !isIncludedIn(name, map(newConfig, prop("name")))), concat(newConfig), uniqueBy(prop("name")));
|
|
8043
|
+
}
|
|
8044
|
+
async function createOrUpdateManifest(manifestData, projectDir) {
|
|
8045
|
+
const manifestPath = join(projectDir, "powerhouse.manifest.json");
|
|
8046
|
+
const existingManifest = await getOrCreateManifestFile(manifestPath);
|
|
8047
|
+
const updatedManifest = {
|
|
8048
|
+
...existingManifest,
|
|
8049
|
+
...manifestData,
|
|
8050
|
+
publisher: merge(existingManifest.publisher, manifestData.publisher),
|
|
8051
|
+
documentModels: makeUpdatedModulesList(existingManifest.documentModels, manifestData.documentModels),
|
|
8052
|
+
editors: makeUpdatedModulesList(existingManifest.editors, manifestData.editors),
|
|
8053
|
+
apps: makeUpdatedModulesList(existingManifest.apps, manifestData.apps),
|
|
8054
|
+
processors: makeUpdatedModulesList(existingManifest.processors, manifestData.processors),
|
|
8055
|
+
subgraphs: makeUpdatedModulesList(existingManifest.subgraphs, manifestData.subgraphs),
|
|
8056
|
+
config: makeUpdatedConfig(existingManifest.config, manifestData.config)
|
|
8057
|
+
};
|
|
8058
|
+
await writeJsonFile(manifestPath, updatedManifest);
|
|
8059
|
+
return updatedManifest;
|
|
8060
|
+
}
|
|
8061
|
+
//#endregion
|
|
8062
|
+
//#region src/file-builders/package-json.ts
|
|
8063
|
+
function makePackageJsonExports() {
|
|
8064
|
+
const standardExportPaths = fromEntries(flatMap(exportPaths, (p) => makePackageJsonExport(p)));
|
|
8065
|
+
return {
|
|
8066
|
+
...rootExportPaths,
|
|
8067
|
+
...standardExportPaths,
|
|
8068
|
+
...nonStandardExportPaths
|
|
8069
|
+
};
|
|
8070
|
+
}
|
|
8071
|
+
function makePackageJsonExport(exportPath) {
|
|
8072
|
+
return [[`./${exportPath}`, {
|
|
8073
|
+
types: `./${exportPath}/dist/index.d.ts`,
|
|
8074
|
+
browser: `./${exportPath}/dist/browser/index.js`,
|
|
8075
|
+
node: `./${exportPath}/dist/node/index.mjs`
|
|
8076
|
+
}], [`./${exportPath}/*`, {
|
|
8077
|
+
types: `./${exportPath}/dist/*/index.d.ts`,
|
|
8078
|
+
browser: `./${exportPath}/dist/browser/*/index.js`,
|
|
8079
|
+
node: `./${exportPath}/dist/node/*/index.mjs`
|
|
8080
|
+
}]];
|
|
8081
|
+
}
|
|
8082
|
+
//#endregion
|
|
8083
|
+
//#region src/file-builders/processors/analytics.ts
|
|
8084
|
+
async function tsMorphGenerateAnalyticsProcessor(args) {
|
|
8085
|
+
const { project, documentTypes, pascalCaseName, dirPath, camelCaseName } = args;
|
|
8086
|
+
await makeIndexFile$1({
|
|
8087
|
+
project,
|
|
8088
|
+
pascalCaseName,
|
|
8089
|
+
dirPath
|
|
8090
|
+
});
|
|
8091
|
+
await makeProcessorFile$1({
|
|
8092
|
+
project,
|
|
8093
|
+
pascalCaseName,
|
|
8094
|
+
dirPath
|
|
8095
|
+
});
|
|
8096
|
+
await makeFactoryFile$1({
|
|
8097
|
+
project,
|
|
8098
|
+
pascalCaseName,
|
|
8099
|
+
camelCaseName,
|
|
8100
|
+
dirPath,
|
|
8101
|
+
documentTypes
|
|
8102
|
+
});
|
|
8103
|
+
}
|
|
8104
|
+
async function makeIndexFile$1(v) {
|
|
8105
|
+
const template = analyticsIndexTemplate;
|
|
8106
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(v.project, path.join(v.dirPath, "index.ts"));
|
|
8107
|
+
if (alreadyExists) return;
|
|
8108
|
+
sourceFile.replaceWithText(template);
|
|
8109
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8110
|
+
}
|
|
8111
|
+
async function makeProcessorFile$1(v) {
|
|
8112
|
+
const template = analyticsProcessorTemplate(v);
|
|
8113
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(v.project, path.join(v.dirPath, "processor.ts"));
|
|
8114
|
+
if (alreadyExists) return;
|
|
8115
|
+
sourceFile.replaceWithText(template);
|
|
8116
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8117
|
+
}
|
|
8118
|
+
async function makeFactoryFile$1(v) {
|
|
8119
|
+
const template = analyticsFactoryTemplate(v);
|
|
8120
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(v.project, path.join(v.dirPath, "factory.ts"));
|
|
8121
|
+
if (alreadyExists) return;
|
|
8122
|
+
sourceFile.replaceWithText(template);
|
|
8123
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8124
|
+
}
|
|
8125
|
+
//#endregion
|
|
8126
|
+
//#region src/file-builders/processors/relational-db.ts
|
|
8127
|
+
async function tsMorphGenerateRelationalDbProcessor(args) {
|
|
8128
|
+
const { project, documentTypes, camelCaseName, pascalCaseName, dirPath } = args;
|
|
8129
|
+
await makeIndexFile({
|
|
8130
|
+
project,
|
|
8131
|
+
pascalCaseName,
|
|
8132
|
+
dirPath
|
|
8133
|
+
});
|
|
8134
|
+
await makeProcessorFile({
|
|
8135
|
+
project,
|
|
8136
|
+
pascalCaseName,
|
|
8137
|
+
dirPath
|
|
8138
|
+
});
|
|
8139
|
+
await makeFactoryFile({
|
|
8140
|
+
project,
|
|
8141
|
+
pascalCaseName,
|
|
8142
|
+
camelCaseName,
|
|
8143
|
+
dirPath,
|
|
8144
|
+
documentTypes
|
|
8145
|
+
});
|
|
8146
|
+
await makeMigrationsFile({
|
|
8147
|
+
project,
|
|
8148
|
+
dirPath
|
|
8149
|
+
});
|
|
8150
|
+
await makeSchemaFile({
|
|
8151
|
+
project,
|
|
8152
|
+
dirPath
|
|
8153
|
+
});
|
|
8154
|
+
}
|
|
8155
|
+
async function makeIndexFile(v) {
|
|
8156
|
+
const template = relationalDbIndexTemplate;
|
|
8157
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(v.project, path.join(v.dirPath, "index.ts"));
|
|
8158
|
+
if (alreadyExists) return;
|
|
8159
|
+
sourceFile.replaceWithText(template);
|
|
8160
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8161
|
+
}
|
|
8162
|
+
async function makeProcessorFile(v) {
|
|
8163
|
+
const template = relationalDbProcessorTemplate(v);
|
|
8164
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(v.project, path.join(v.dirPath, "processor.ts"));
|
|
8165
|
+
if (alreadyExists) return;
|
|
8166
|
+
sourceFile.replaceWithText(template);
|
|
8167
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8168
|
+
}
|
|
8169
|
+
async function makeFactoryFile(v) {
|
|
8170
|
+
const template = relationalDbFactoryTemplate(v);
|
|
8171
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(v.project, path.join(v.dirPath, "factory.ts"));
|
|
8172
|
+
if (alreadyExists) return;
|
|
8173
|
+
sourceFile.replaceWithText(template);
|
|
8174
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8175
|
+
}
|
|
8176
|
+
async function makeSchemaFile(v) {
|
|
8177
|
+
const template = relationalDbSchemaTemplate();
|
|
8178
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(v.project, path.join(v.dirPath, "schema.ts"));
|
|
8179
|
+
if (alreadyExists) return;
|
|
8180
|
+
sourceFile.replaceWithText(template);
|
|
8181
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8182
|
+
}
|
|
8183
|
+
async function makeMigrationsFile(v) {
|
|
8184
|
+
const template = relationalDbMigrationsTemplate();
|
|
8185
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(v.project, path.join(v.dirPath, "migrations.ts"));
|
|
8186
|
+
if (alreadyExists) return;
|
|
8187
|
+
sourceFile.replaceWithText(template);
|
|
8188
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8189
|
+
}
|
|
8190
|
+
//#endregion
|
|
8191
|
+
//#region src/file-builders/processors/processor.ts
|
|
8192
|
+
async function tsMorphGenerateProcessor(args) {
|
|
8193
|
+
const { project, processorName, documentTypes, processorType, processorApps } = args;
|
|
8194
|
+
const kebabCaseName = kebabCase(processorName);
|
|
8195
|
+
const camelCaseName = camelCase(processorName);
|
|
8196
|
+
const pascalCaseName = pascalCase(processorName);
|
|
8197
|
+
const { directory: processorsDir } = getOrCreateDirectory(project, "processors");
|
|
8198
|
+
const projectDir = processorsDir.getParentOrThrow().getPath();
|
|
8199
|
+
const processorsDirPath = processorsDir.getPath();
|
|
8200
|
+
const dirPath = path.join(processorsDirPath, kebabCaseName);
|
|
8201
|
+
await ensureDirectoriesExist(project, processorsDirPath, dirPath);
|
|
8202
|
+
if (processorType === "analytics") await tsMorphGenerateAnalyticsProcessor({
|
|
8203
|
+
processorName,
|
|
8204
|
+
documentTypes,
|
|
8205
|
+
camelCaseName,
|
|
8206
|
+
dirPath,
|
|
8207
|
+
kebabCaseName,
|
|
8208
|
+
pascalCaseName,
|
|
8209
|
+
processorsDirPath,
|
|
8210
|
+
project
|
|
8211
|
+
});
|
|
8212
|
+
else await tsMorphGenerateRelationalDbProcessor({
|
|
8213
|
+
processorName,
|
|
8214
|
+
documentTypes,
|
|
8215
|
+
camelCaseName,
|
|
8216
|
+
dirPath,
|
|
8217
|
+
kebabCaseName,
|
|
8218
|
+
pascalCaseName,
|
|
8219
|
+
processorsDirPath,
|
|
8220
|
+
project
|
|
8221
|
+
});
|
|
8222
|
+
for (const processorApp of processorApps) await updateFactoryBuildersFile({
|
|
8223
|
+
processorsDirPath,
|
|
8224
|
+
processorApp,
|
|
8225
|
+
project,
|
|
8226
|
+
camelCaseName,
|
|
8227
|
+
kebabCaseName
|
|
8228
|
+
});
|
|
8229
|
+
await createOrUpdateManifest({ processors: [{
|
|
8230
|
+
name: processorName,
|
|
8231
|
+
id: kebabCaseName
|
|
8232
|
+
}] }, projectDir);
|
|
8233
|
+
}
|
|
8234
|
+
async function updateFactoryBuildersFile(v) {
|
|
8235
|
+
const { project, processorsDirPath, processorApp, camelCaseName, kebabCaseName } = v;
|
|
8236
|
+
const template = factoryBuildersTemplate;
|
|
8237
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(processorsDirPath, `${processorApp}.ts`));
|
|
8238
|
+
if (!alreadyExists) sourceFile.replaceWithText(template);
|
|
8239
|
+
const name = `${camelCaseName}FactoryBuilder`;
|
|
8240
|
+
const moduleSpecifier = path.join("processors", kebabCaseName);
|
|
8241
|
+
const factoriesArrayName = "processorFactoryBuilders";
|
|
8242
|
+
let factoryBuildersArray = getFactoryBuildersArray(sourceFile, factoriesArrayName);
|
|
8243
|
+
if (!factoryBuildersArray) {
|
|
8244
|
+
sourceFile.replaceWithText(template);
|
|
8245
|
+
factoryBuildersArray = getFactoryBuildersArray(sourceFile, factoriesArrayName);
|
|
8246
|
+
}
|
|
8247
|
+
if (!factoryBuildersArray) throw new Error(`Could not get factory builders array in file ${processorApp}.ts`);
|
|
8248
|
+
if (!sourceFile.getImportDeclarations().flatMap((importDeclaration) => importDeclaration.getNamedImports().map((n) => n.getText())).find((n) => n === name)) sourceFile.addImportDeclaration({
|
|
8249
|
+
namedImports: [name],
|
|
8250
|
+
moduleSpecifier
|
|
8251
|
+
});
|
|
8252
|
+
if (!factoryBuildersArray.getElements().map((e) => e.getText()).includes(name)) factoryBuildersArray.addElement(name);
|
|
8253
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8254
|
+
}
|
|
8255
|
+
function getFactoryBuildersArray(sourceFile, name) {
|
|
8256
|
+
return sourceFile.getDescendantsOfKind(ts.SyntaxKind.VariableStatement).flatMap((d) => d.getDescendantsOfKind(ts.SyntaxKind.VariableDeclaration)).find((d) => d.getName() === name)?.getDescendantsOfKind(ts.SyntaxKind.ArrayLiteralExpression).at(0);
|
|
8257
|
+
}
|
|
8258
|
+
//#endregion
|
|
8259
|
+
//#region src/file-builders/subgraphs.ts
|
|
8260
|
+
async function tsMorphGenerateSubgraph(args) {
|
|
8261
|
+
const { subgraphName, project } = args;
|
|
8262
|
+
const kebabCaseName = kebabCase(subgraphName);
|
|
8263
|
+
const pascalCaseName = pascalCase(subgraphName);
|
|
8264
|
+
const camelCaseName = camelCase(subgraphName);
|
|
8265
|
+
const { directory: subgraphsDir } = getOrCreateDirectory(project, "subgraphs");
|
|
8266
|
+
const subgraphsDirPath = subgraphsDir.getPath();
|
|
8267
|
+
const projectDir = subgraphsDir.getParentOrThrow().getPath();
|
|
8268
|
+
const subgraphDir = path.join(subgraphsDirPath, kebabCaseName);
|
|
8269
|
+
await ensureDirectoriesExist(project, subgraphsDirPath, subgraphDir);
|
|
8270
|
+
await makeBaseSubgraphIndexFile(project, subgraphDir, {
|
|
8271
|
+
pascalCaseName,
|
|
8272
|
+
kebabCaseName
|
|
8273
|
+
});
|
|
8274
|
+
await makeBaseSubgraphLibFile(project, subgraphDir);
|
|
8275
|
+
await makeCustomSubgraphFiles(project, subgraphDir, {
|
|
8276
|
+
pascalCaseName,
|
|
8277
|
+
camelCaseName
|
|
8278
|
+
});
|
|
8279
|
+
await makeSubgraphsIndexFile({
|
|
8280
|
+
project,
|
|
8281
|
+
subgraphsDir: subgraphsDirPath
|
|
8282
|
+
});
|
|
8283
|
+
await createOrUpdateManifest({ subgraphs: [{
|
|
8284
|
+
name: subgraphName,
|
|
8285
|
+
id: kebabCaseName
|
|
8286
|
+
}] }, projectDir);
|
|
8287
|
+
}
|
|
8288
|
+
async function makeBaseSubgraphIndexFile(project, dirPath, v) {
|
|
8289
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(dirPath, "index.ts"));
|
|
8290
|
+
if (alreadyExists) return;
|
|
8291
|
+
sourceFile.replaceWithText(subgraphIndexFileTemplate(v));
|
|
8292
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8293
|
+
}
|
|
8294
|
+
async function makeBaseSubgraphLibFile(project, dirPath) {
|
|
8295
|
+
const { alreadyExists, sourceFile } = getOrCreateSourceFile(project, path.join(dirPath, "lib.ts"));
|
|
8296
|
+
if (alreadyExists) return;
|
|
8297
|
+
sourceFile.replaceWithText(subgraphLibFileTemplate());
|
|
8298
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
8299
|
+
}
|
|
8300
|
+
async function makeCustomSubgraphFiles(project, dirPath, v) {
|
|
8301
|
+
const schema = getOrCreateSourceFile(project, path.join(dirPath, "schema.ts"));
|
|
8302
|
+
if (!schema.alreadyExists) schema.sourceFile.replaceWithText(customSubgraphSchemaTemplate(v));
|
|
8303
|
+
const resolvers = getOrCreateSourceFile(project, path.join(dirPath, "resolvers.ts"));
|
|
8304
|
+
if (!resolvers.alreadyExists) {
|
|
8305
|
+
resolvers.sourceFile.replaceWithText(customSubgraphResolversTemplate(v));
|
|
8306
|
+
await formatSourceFileWithPrettier(resolvers.sourceFile);
|
|
8307
|
+
}
|
|
6379
8308
|
}
|
|
6380
|
-
function
|
|
6381
|
-
const
|
|
6382
|
-
|
|
8309
|
+
async function makeSubgraphsIndexFile(args) {
|
|
8310
|
+
const { project, subgraphsDir } = args;
|
|
8311
|
+
const { sourceFile } = getOrCreateSourceFile(project, path.join(subgraphsDir, "index.ts"));
|
|
8312
|
+
const existingExportNames = pipe(sourceFile.getExportDeclarations(), map((exportDeclaration) => exportDeclaration.getNamespaceExport()?.getName()), filter(isTruthy));
|
|
8313
|
+
const exportDeclarations = pipe(project.getDirectoryOrThrow(subgraphsDir).getDescendantSourceFiles(), filter((sourceFile) => sourceFile.getBaseName() === "index.ts"), uniqueBy((sourceFile) => sourceFile.getFilePath()), map((sourceFile) => sourceFile.getClasses().find((c) => c.getBaseClass()?.getText().includes("BaseSubgraph"))), filter(isTruthy), map((classDeclaration) => ({
|
|
8314
|
+
name: classDeclaration.getNameOrThrow(),
|
|
8315
|
+
subgraphDir: classDeclaration.getSourceFile().getDirectory().getBaseName()
|
|
8316
|
+
})), filter(({ name }) => !existingExportNames.includes(name)), map(({ name, subgraphDir }) => ({
|
|
8317
|
+
namespaceExport: name,
|
|
8318
|
+
moduleSpecifier: `./${subgraphDir}/index.js`
|
|
8319
|
+
})));
|
|
8320
|
+
sourceFile.addExportDeclarations(exportDeclarations);
|
|
8321
|
+
await formatSourceFileWithPrettier(sourceFile);
|
|
6383
8322
|
}
|
|
6384
8323
|
//#endregion
|
|
6385
|
-
export {
|
|
8324
|
+
export { ensureDirectoriesExist as $, folderTreeFileTemplate as $n, getLatestDocumentModelSpec as $t, writeAllGeneratedProjectFiles as A, licenseTemplate as An, makeOperationImportNames as At, makeEditorModuleFile as B, upgradeManifestsTemplate as Bn, documentModelGenTypesTemplate as Bt, rootExportPaths as C, packageJsonExportsTemplate as Cn, analyticsProcessorTemplate as Ct, writeCliDocsMarkdownFile as D, npmrcTemplate as Dn, upgradeTransitionTemplate as Dt, makeCliDocsFromHelp as E, packageJsonTemplate as En, documentModelUtilsTemplate as Et, writeGeneratedProjectRootFiles as F, syncAndPublishWorkflowTemplate as Fn, documentModelSrcIndexFileTemplate as Ft, DEFAULT_PROJECT_OPTIONS as G, dockerfileTemplate as Gn, documentModelOperationsModuleErrorFileTemplate as Gt, makeEditorsIndexFile as H, documentModelsTemplate as Hn, documentModelGenReducerFileTemplate as Ht, writeGeneratedSubgraphsFiles as I, geminiSettingsTemplate as In, documentModelModuleFileTemplate as It, getObjectLiteral as J, claudeSettingsLocalTemplate as Jn, getModuleExportType as Jt, buildTsMorphProject as K, connectEntrypointTemplate as Kn, documentModelOperationsModuleCreatorsFileTemplate as Kt, writeModuleFiles as L, eslintConfigTemplate as Ln, documentModelIndexTemplate as Lt, writeGeneratedDocumentModelsFiles as M, legacyIndexHtmlTemplate as Mn, makeTestCaseForOperation as Mt, writeGeneratedEditorsFiles as N, indexHtmlTemplate as Nn, documentModelTestFileTemplate as Nt, buildBoilerplatePackageJson as O, mcpTemplate as On, upgradeManifestTemplate as Ot, writeGeneratedProcessorsFiles as P, gitIgnoreTemplate as Pn, documentModelSrcUtilsTemplate as Pt, buildStringLiteral as Q, driveExplorerNavigationBreadcrumbsFileTemplate as Qn, getEditorVariableNames as Qt, writeProjectRootFiles as R, editorsIndexTemplate as Rn, documentModelHooksFileTemplate as Rt, packageScripts as S, buildPowerhouseConfigTemplate as Sn, factoryBuildersTemplate as St, getCommandsHelpInfo as T, exportsTemplate as Tn, analyticsFactoryTemplate as Tt, validateDocumentModelState as U, switchboardEntrypointTemplate as Un, documentModelPhFactoriesFileTemplate as Ut, makeEditorsFile as V, documentModelsIndexTemplate as Vn, documentModelSchemaIndexTemplate as Vt, getInitialStates as W, nginxConfTemplate as Wn, documentModelOperationsModuleOperationsFileTemplate as Wt, getVariableDeclarationByTypeName as X, appEditorFileTemplate as Xn, getDocumentModelSpecByVersionNumber as Xt, getObjectProperty as Y, agentsTemplate as Yn, getDocumentModelDirName as Yt, buildObjectLiteral as Z, appConfigFileTemplate as Zn, getDocumentModelVariableNames as Zt, defaultManifest as _, tsconfigPathsTemplate as _n, relationalDbMigrationsTemplate as _t, createOrUpdateManifest as a, documentModelGenIndexFileTemplate as an, createDocumentFileTemplate as ar, runPrettier as at, externalDevDependencies as b, readmeTemplate as bn, processorsIndexTemplate as bt, operationHasAttachment as c, documentModelGenCreatorsFileTemplate as cn, configSpec as ct, tsMorphGenerateDocumentModel as d, documentModelRootActionsFileTemplate as dn, customSubgraphResolversTemplate as dt, getLatestDocumentModelSpecVersionNumber as en, appFoldersFileTemplate as er, getOrCreateDirectory as et, generateDocumentModelZodSchemas as f, documentEditorModuleFileTemplate as fn, customSubgraphSchemaTemplate as ft, tsMorphGenerateDocumentEditor as g, tsConfigTemplate as gn, relationalDbProcessorTemplate as gt, scalarsValidation as h, vitestConfigTemplate as hn, relationalDbSchemaTemplate as ht, makePackageJsonExports as i, getActionTypeName as in, appDriveContentsFileTemplate as ir, formatSourceFileWithPrettier as it, writeCIFiles as j, indexTsTemplate as jn, makeOperationsImports as jt, writeAiConfigFiles as k, mainTsxTemplate as kn, documentModelOperationsModuleTestFileTemplate as kt, operationHasEmptyInput as l, documentModelGenControllerFileTemplate as ln, parseArgs as lt, scalars as m, docsFromCliHelpTemplate as mn, subgraphIndexFileTemplate as mt, tsMorphGenerateSubgraph as n, getActionInputTypeNames as nn, emptyStateFileTemplate as nr, getPreviousVersionSourceFile as nt, getOrCreateManifestFile as o, documentModelDocumentTypeTemplate as on, getDocumentTypeMetadata as ot, generateTypesAndZodSchemasFromGraphql as p, documentEditorEditorFileTemplate as pn, subgraphLibFileTemplate as pt, getDefaultProjectOptions as q, cursorMcpTemplate as qn, documentModelOperationModuleActionsFileTemplate as qt, tsMorphGenerateProcessor as r, getActionType as rn, driveExplorerFileTemplate as rr, formatSafe as rt, makeModulesIndexFile as s, documentModelDocumentSchemaFileTemplate as sn, documentModelDocumentTypeMetadata as st, makeSubgraphsIndexFile as t, getActionInputName as tn, appFilesFileTemplate as tr, getOrCreateSourceFile as tt, operationHasInput as u, documentModelGenActionsFileTemplate as un, parseConfig as ut, exportPaths as v, subgraphsIndexTemplate as vn, relationalDbIndexTemplate as vt, getCommandHelpInfo as w, packageJsonScriptsTemplate as wn, analyticsIndexTemplate as wt, nonStandardExportPaths as x, ManifestTemplate as xn, processorsFactoryTemplate as xt, externalDependencies as y, styleTemplate as yn, relationalDbFactoryTemplate as yt, tsMorphGenerateApp as z, editorsTemplate as zn, documentModelGenUtilsTemplate as zt };
|
|
6386
8325
|
|
|
6387
|
-
//# sourceMappingURL=
|
|
8326
|
+
//# sourceMappingURL=file-builders-BkbVW0kT.mjs.map
|