@webiny/project 0.0.0-unstable.df7a8bb475 → 0.0.0-unstable.e2758ee1cf

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/ProjectSdk.d.ts +1 -0
  2. package/ProjectSdk.js +4 -1
  3. package/ProjectSdk.js.map +1 -1
  4. package/abstractions/features/GetFeatureFlags.d.ts +8 -0
  5. package/abstractions/features/GetFeatureFlags.js +4 -0
  6. package/abstractions/features/GetFeatureFlags.js.map +1 -0
  7. package/abstractions/features/index.d.ts +1 -0
  8. package/abstractions/features/index.js +1 -0
  9. package/abstractions/features/index.js.map +1 -1
  10. package/abstractions/services/WatchedLambdaFunctionsService.d.ts +12 -7
  11. package/abstractions/services/WatchedLambdaFunctionsService.js.map +1 -1
  12. package/components/Wcp.d.ts +2 -0
  13. package/components/Wcp.js +8 -1
  14. package/components/Wcp.js.map +1 -1
  15. package/createProjectSdkContainer.js +4 -1
  16. package/createProjectSdkContainer.js.map +1 -1
  17. package/decorators/DeployAppClearWatchedLambdaFunctions.d.ts +3 -2
  18. package/decorators/DeployAppClearWatchedLambdaFunctions.js +11 -5
  19. package/decorators/DeployAppClearWatchedLambdaFunctions.js.map +1 -1
  20. package/decorators/DeployAppWithWatchedLambdaReplacement.d.ts +3 -2
  21. package/decorators/DeployAppWithWatchedLambdaReplacement.js +16 -7
  22. package/decorators/DeployAppWithWatchedLambdaReplacement.js.map +1 -1
  23. package/decorators/GetFeatureFlagsWithLicense.d.ts +13 -0
  24. package/decorators/GetFeatureFlagsWithLicense.js +71 -0
  25. package/decorators/GetFeatureFlagsWithLicense.js.map +1 -0
  26. package/decorators/index.d.ts +1 -0
  27. package/decorators/index.js +1 -0
  28. package/decorators/index.js.map +1 -1
  29. package/defineExtension/createExtensionReactComponent.js +2 -6
  30. package/defineExtension/createExtensionReactComponent.js.map +1 -1
  31. package/defineExtension/index.d.ts +0 -1
  32. package/defineExtension/index.js +0 -1
  33. package/defineExtension/index.js.map +1 -1
  34. package/defineExtension/zodTypes/zodSrcPath.d.ts +1 -0
  35. package/defineExtension/zodTypes/zodSrcPath.js +7 -14
  36. package/defineExtension/zodTypes/zodSrcPath.js.map +1 -1
  37. package/exports/infra/index.d.ts +1 -1
  38. package/exports/infra/index.js +1 -1
  39. package/exports/infra/index.js.map +1 -1
  40. package/extensions/AdminBuildParam.d.ts +11 -0
  41. package/extensions/AdminBuildParam.js +184 -0
  42. package/extensions/AdminBuildParam.js.map +1 -0
  43. package/extensions/AdminExtension.d.ts +11 -0
  44. package/extensions/AdminExtension.js +99 -0
  45. package/extensions/AdminExtension.js.map +1 -0
  46. package/extensions/ApiBuildParam.d.ts +11 -0
  47. package/extensions/ApiBuildParam.js +119 -0
  48. package/extensions/ApiBuildParam.js.map +1 -0
  49. package/extensions/ApiExtension.d.ts +11 -0
  50. package/{defineExtension/defineApiExtension.js → extensions/ApiExtension.js} +14 -22
  51. package/extensions/ApiExtension.js.map +1 -0
  52. package/extensions/FeatureFlags.d.ts +92 -0
  53. package/extensions/FeatureFlags.js +43 -0
  54. package/extensions/FeatureFlags.js.map +1 -0
  55. package/extensions/index.d.ts +109 -0
  56. package/extensions/index.js +12 -2
  57. package/extensions/index.js.map +1 -1
  58. package/features/GetFeatureFlags/GetFeatureFlags.d.ts +10 -0
  59. package/features/GetFeatureFlags/GetFeatureFlags.js +29 -0
  60. package/features/GetFeatureFlags/GetFeatureFlags.js.map +1 -0
  61. package/features/GetFeatureFlags/index.d.ts +1 -0
  62. package/features/GetFeatureFlags/index.js +3 -0
  63. package/features/GetFeatureFlags/index.js.map +1 -0
  64. package/features/Watch/Watch.js +1 -0
  65. package/features/Watch/Watch.js.map +1 -1
  66. package/features/Watch/replaceLambdaFunctions.d.ts +2 -1
  67. package/features/Watch/replaceLambdaFunctions.js +5 -1
  68. package/features/Watch/replaceLambdaFunctions.js.map +1 -1
  69. package/features/index.d.ts +1 -0
  70. package/features/index.js +1 -0
  71. package/features/index.js.map +1 -1
  72. package/index.d.ts +1 -0
  73. package/index.js +1 -0
  74. package/index.js.map +1 -1
  75. package/package.json +17 -16
  76. package/services/GetProjectConfigService/WcpProjectLicenseContext.d.ts +1 -0
  77. package/services/GetProjectConfigService/WcpProjectLicenseContext.js +2 -1
  78. package/services/GetProjectConfigService/WcpProjectLicenseContext.js.map +1 -1
  79. package/services/InitProjectSdkService/registerDecorators.js +2 -2
  80. package/services/InitProjectSdkService/registerDecorators.js.map +1 -1
  81. package/services/InitProjectSdkService/registerHooks.js +2 -2
  82. package/services/InitProjectSdkService/registerHooks.js.map +1 -1
  83. package/services/InitProjectSdkService/registerImplementations.js +2 -2
  84. package/services/InitProjectSdkService/registerImplementations.js.map +1 -1
  85. package/services/InitProjectSdkService/registerPulumiExtensions.js +2 -2
  86. package/services/InitProjectSdkService/registerPulumiExtensions.js.map +1 -1
  87. package/services/InstallExtensionService/InstallExtensionService.d.ts +1 -1
  88. package/services/InstallExtensionService/InstallExtensionService.js +3 -3
  89. package/services/InstallExtensionService/InstallExtensionService.js.map +1 -1
  90. package/services/InstallExtensionService/mergePackageJson.js +4 -4
  91. package/services/InstallExtensionService/mergePackageJson.js.map +1 -1
  92. package/services/ListAppLambdaFunctionsService/ListAppLambdaFunctionsService.js +1 -1
  93. package/services/ListAppLambdaFunctionsService/ListAppLambdaFunctionsService.js.map +1 -1
  94. package/services/SetProjectIdService/SetProjectIdService.js +28 -18
  95. package/services/SetProjectIdService/SetProjectIdService.js.map +1 -1
  96. package/services/WatchedLambdaFunctionsService/WatchedLambdaFunctionsService.d.ts +4 -4
  97. package/services/WatchedLambdaFunctionsService/WatchedLambdaFunctionsService.js +26 -20
  98. package/services/WatchedLambdaFunctionsService/WatchedLambdaFunctionsService.js.map +1 -1
  99. package/utils/ExtensionSrcResolver.d.ts +33 -0
  100. package/utils/ExtensionSrcResolver.js +119 -0
  101. package/utils/ExtensionSrcResolver.js.map +1 -0
  102. package/utils/index.d.ts +1 -1
  103. package/utils/index.js +1 -1
  104. package/utils/index.js.map +1 -1
  105. package/defineExtension/defineApiExtension.d.ts +0 -17
  106. package/defineExtension/defineApiExtension.js.map +0 -1
  107. package/exports/extensions.d.ts +0 -1
  108. package/exports/extensions.js +0 -3
  109. package/exports/extensions.js.map +0 -1
  110. package/utils/ImplPathResolver.d.ts +0 -10
  111. package/utils/ImplPathResolver.js +0 -27
  112. package/utils/ImplPathResolver.js.map +0 -1
@@ -0,0 +1,71 @@
1
+ import { License } from "@webiny/wcp";
2
+ import { FeatureFlags } from "@webiny/feature-flags";
3
+ import { GetFeatureFlags } from "../abstractions/index.js";
4
+
5
+ /* Returns the user's value when the license permits it, otherwise false.
6
+ * This preserves an explicit user false (opt-out), while blocking features
7
+ * the license doesn't cover. */
8
+ function applyLicenseFlag(userValue, licenseAllows) {
9
+ return licenseAllows ? userValue : false;
10
+ }
11
+ class GetFeatureFlagsWithLicenseDecorator {
12
+ constructor(decoratee) {
13
+ this.decoratee = decoratee;
14
+ }
15
+ async execute() {
16
+ const userFlags = await this.decoratee.execute();
17
+ const license = this.getLicenseFromEnv();
18
+ // toDto() returns a structuredClone, so we can safely mutate it in applyLicense.
19
+ return FeatureFlags.fromDto(this.applyLicense(userFlags.toDto(), license));
20
+ }
21
+ getLicenseFromEnv() {
22
+ const licenseEnv = process.env.WCP_PROJECT_LICENSE;
23
+ if (!licenseEnv) {
24
+ return License.fromLicenseDto(null);
25
+ }
26
+ try {
27
+ const licenseDto = JSON.parse(licenseEnv);
28
+ return License.fromLicenseDto(licenseDto);
29
+ } catch {
30
+ return License.fromLicenseDto(null);
31
+ }
32
+ }
33
+
34
+ /* For each licensable flag: final = user_value && license_allows.
35
+ * If the user disables a feature they have access to, we respect false.
36
+ * If the user enables a feature the license doesn't allow, we force false.
37
+ * fileManager (base) is always allowed; only threatDetection is restricted. */
38
+ applyLicense(featureFlagsDto, license) {
39
+ featureFlagsDto.multiTenancy = applyLicenseFlag(featureFlagsDto.multiTenancy, license.canUseFeature("multiTenancy"));
40
+ featureFlagsDto.advancedPublishingWorkflow = applyLicenseFlag(featureFlagsDto.advancedPublishingWorkflow, license.canUseWorkflows());
41
+
42
+ // advancedAccessControlLayer.
43
+ if (featureFlagsDto.advancedAccessControlLayer !== false) {
44
+ if (!license.canUseAacl()) {
45
+ // License doesn't allow AACL at all.
46
+ featureFlagsDto.advancedAccessControlLayer = false;
47
+ } else if (typeof featureFlagsDto.advancedAccessControlLayer === "object") {
48
+ // License allows AACL; constrain sub-options.
49
+ const aacl = featureFlagsDto.advancedAccessControlLayer;
50
+ aacl.teams = applyLicenseFlag(aacl.teams, license.canUseTeams());
51
+ aacl.privateFiles = applyLicenseFlag(aacl.privateFiles, license.canUsePrivateFiles());
52
+ aacl.folderLevelPermissions = applyLicenseFlag(aacl.folderLevelPermissions, license.canUseFolderLevelPermissions());
53
+ }
54
+ }
55
+ featureFlagsDto.auditLogs = applyLicenseFlag(featureFlagsDto.auditLogs, license.canUseAuditLogs());
56
+ featureFlagsDto.recordLocking = applyLicenseFlag(featureFlagsDto.recordLocking, license.canUseRecordLocking());
57
+
58
+ // fileManager is always enabled; only restrict threatDetection via license.
59
+ if (!featureFlagsDto.fileManager) {
60
+ featureFlagsDto.fileManager = {};
61
+ }
62
+ featureFlagsDto.fileManager.threatDetection = applyLicenseFlag(featureFlagsDto.fileManager.threatDetection, license.canUseFileManagerThreatDetection());
63
+ return featureFlagsDto;
64
+ }
65
+ }
66
+ export const getFeatureFlagsWithLicense = GetFeatureFlags.createDecorator({
67
+ decorator: GetFeatureFlagsWithLicenseDecorator,
68
+ dependencies: []
69
+ });
70
+
71
+ //# sourceMappingURL=GetFeatureFlagsWithLicense.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["License","FeatureFlags","GetFeatureFlags","applyLicenseFlag","userValue","licenseAllows","GetFeatureFlagsWithLicenseDecorator","constructor","decoratee","execute","userFlags","license","getLicenseFromEnv","fromDto","applyLicense","toDto","licenseEnv","process","env","WCP_PROJECT_LICENSE","fromLicenseDto","licenseDto","JSON","parse","featureFlagsDto","multiTenancy","canUseFeature","advancedPublishingWorkflow","canUseWorkflows","advancedAccessControlLayer","canUseAacl","aacl","teams","canUseTeams","privateFiles","canUsePrivateFiles","folderLevelPermissions","canUseFolderLevelPermissions","auditLogs","canUseAuditLogs","recordLocking","canUseRecordLocking","fileManager","threatDetection","canUseFileManagerThreatDetection","getFeatureFlagsWithLicense","createDecorator","decorator","dependencies"],"sources":["GetFeatureFlagsWithLicense.ts"],"sourcesContent":["import { License } from \"@webiny/wcp\";\nimport type { ILicense, DecryptedWcpProjectLicense } from \"@webiny/wcp/types.js\";\nimport { FeatureFlags } from \"@webiny/feature-flags\";\nimport type { IFeatureFlagsDto, IAaclFeatureFlags } from \"@webiny/feature-flags\";\nimport { GetFeatureFlags } from \"~/abstractions/index.js\";\n\n/* Returns the user's value when the license permits it, otherwise false.\n * This preserves an explicit user false (opt-out), while blocking features\n * the license doesn't cover. */\nfunction applyLicenseFlag<T extends boolean | undefined>(\n userValue: T,\n licenseAllows: boolean\n): T | false {\n return licenseAllows ? userValue : false;\n}\n\nclass GetFeatureFlagsWithLicenseDecorator implements GetFeatureFlags.Interface {\n constructor(private decoratee: GetFeatureFlags.Interface) {}\n\n async execute(): Promise<FeatureFlags> {\n const userFlags = await this.decoratee.execute();\n const license = this.getLicenseFromEnv();\n // toDto() returns a structuredClone, so we can safely mutate it in applyLicense.\n return FeatureFlags.fromDto(this.applyLicense(userFlags.toDto(), license));\n }\n\n private getLicenseFromEnv(): ILicense {\n const licenseEnv = process.env.WCP_PROJECT_LICENSE;\n if (!licenseEnv) {\n return License.fromLicenseDto(null);\n }\n\n try {\n const licenseDto = JSON.parse(licenseEnv) as DecryptedWcpProjectLicense;\n return License.fromLicenseDto(licenseDto);\n } catch {\n return License.fromLicenseDto(null);\n }\n }\n\n /* For each licensable flag: final = user_value && license_allows.\n * If the user disables a feature they have access to, we respect false.\n * If the user enables a feature the license doesn't allow, we force false.\n * fileManager (base) is always allowed; only threatDetection is restricted. */\n private applyLicense(featureFlagsDto: IFeatureFlagsDto, license: ILicense): IFeatureFlagsDto {\n featureFlagsDto.multiTenancy = applyLicenseFlag(\n featureFlagsDto.multiTenancy,\n license.canUseFeature(\"multiTenancy\")\n );\n\n featureFlagsDto.advancedPublishingWorkflow = applyLicenseFlag(\n featureFlagsDto.advancedPublishingWorkflow,\n license.canUseWorkflows()\n );\n\n // advancedAccessControlLayer.\n if (featureFlagsDto.advancedAccessControlLayer !== false) {\n if (!license.canUseAacl()) {\n // License doesn't allow AACL at all.\n featureFlagsDto.advancedAccessControlLayer = false;\n } else if (typeof featureFlagsDto.advancedAccessControlLayer === \"object\") {\n // License allows AACL; constrain sub-options.\n const aacl = featureFlagsDto.advancedAccessControlLayer as IAaclFeatureFlags;\n aacl.teams = applyLicenseFlag(aacl.teams, license.canUseTeams());\n aacl.privateFiles = applyLicenseFlag(\n aacl.privateFiles,\n license.canUsePrivateFiles()\n );\n aacl.folderLevelPermissions = applyLicenseFlag(\n aacl.folderLevelPermissions,\n license.canUseFolderLevelPermissions()\n );\n }\n }\n\n featureFlagsDto.auditLogs = applyLicenseFlag(\n featureFlagsDto.auditLogs,\n license.canUseAuditLogs()\n );\n featureFlagsDto.recordLocking = applyLicenseFlag(\n featureFlagsDto.recordLocking,\n license.canUseRecordLocking()\n );\n\n // fileManager is always enabled; only restrict threatDetection via license.\n if (!featureFlagsDto.fileManager) {\n featureFlagsDto.fileManager = {};\n }\n featureFlagsDto.fileManager.threatDetection = applyLicenseFlag(\n featureFlagsDto.fileManager.threatDetection,\n license.canUseFileManagerThreatDetection()\n );\n\n return featureFlagsDto;\n }\n}\n\nexport const getFeatureFlagsWithLicense = GetFeatureFlags.createDecorator({\n decorator: GetFeatureFlagsWithLicenseDecorator,\n dependencies: []\n});\n"],"mappings":"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","ignoreList":[]}
@@ -5,3 +5,4 @@ export * from "./DeployAppWithHooks.js";
5
5
  export * from "./DeployAppWithWatchedLambdaReplacement.js";
6
6
  export * from "./WatchWithHooks.js";
7
7
  export * from "./GetPulumiServiceWithDownloadInfo.js";
8
+ export * from "./GetFeatureFlagsWithLicense.js";
@@ -5,5 +5,6 @@ export * from "./DeployAppWithHooks.js";
5
5
  export * from "./DeployAppWithWatchedLambdaReplacement.js";
6
6
  export * from "./WatchWithHooks.js";
7
7
  export * from "./GetPulumiServiceWithDownloadInfo.js";
8
+ export * from "./GetFeatureFlagsWithLicense.js";
8
9
 
9
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./BuildAppWithHooks.js\";\nexport * from \"./DeployAppClearWatchedLambdaFunctions.js\";\nexport * from \"./DeployAppRefreshStackOutputCache.js\";\nexport * from \"./DeployAppWithHooks.js\";\nexport * from \"./DeployAppWithWatchedLambdaReplacement.js\";\nexport * from \"./WatchWithHooks.js\";\nexport * from \"./GetPulumiServiceWithDownloadInfo.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./BuildAppWithHooks.js\";\nexport * from \"./DeployAppClearWatchedLambdaFunctions.js\";\nexport * from \"./DeployAppRefreshStackOutputCache.js\";\nexport * from \"./DeployAppWithHooks.js\";\nexport * from \"./DeployAppWithWatchedLambdaReplacement.js\";\nexport * from \"./WatchWithHooks.js\";\nexport * from \"./GetPulumiServiceWithDownloadInfo.js\";\nexport * from \"./GetFeatureFlagsWithLicense.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","ignoreList":[]}
@@ -13,10 +13,6 @@ const KeyValues = props => {
13
13
  };
14
14
  export function createExtensionReactComponent(extensionParams) {
15
15
  const ExtensionReactComponent = props => {
16
- // If custom render function is provided, use it.
17
- if (extensionParams.render) {
18
- return /*#__PURE__*/React.createElement(React.Fragment, null, extensionParams.render(props));
19
- }
20
16
  const {
21
17
  name,
22
18
  remove,
@@ -39,14 +35,14 @@ export function createExtensionReactComponent(extensionParams) {
39
35
 
40
36
  // @ts-expect-error move KeyValues back inside the Property component to avoid this error
41
37
  const KeyValuesComponent = parentProps => /*#__PURE__*/React.createElement(KeyValues, Object.assign({}, parentProps, keyValues));
42
- return /*#__PURE__*/React.createElement(Property, {
38
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Property, {
43
39
  id: propertyId,
44
40
  name: propertyName,
45
41
  array: extensionParams.multiple,
46
42
  remove: remove,
47
43
  before: placeBefore,
48
44
  after: placeAfter
49
- }, /*#__PURE__*/React.createElement(KeyValuesComponent, null));
45
+ }, /*#__PURE__*/React.createElement(KeyValuesComponent, null)), extensionParams.render && extensionParams.render(props));
50
46
  };
51
47
  ExtensionReactComponent.displayName = `ExtensionReactComponent(${extensionParams.type})`;
52
48
  return ExtensionReactComponent;
@@ -1 +1 @@
1
- {"version":3,"names":["React","useMemo","Property","useIdGenerator","KeyValues","props","getId","Object","entries","map","key","value","createElement","name","id","createExtensionReactComponent","extensionParams","ExtensionReactComponent","render","Fragment","remove","before","after","keyValues","type","propertyId","multiple","undefined","propertyName","placeAfter","placeBefore","KeyValuesComponent","parentProps","assign","array","displayName"],"sources":["createExtensionReactComponent.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { Property, useIdGenerator } from \"@webiny/react-properties\";\nimport { type DefineExtensionParams } from \"./types.js\";\nimport { type z } from \"zod\";\n\nconst KeyValues = (props: Record<string, any>) => {\n const getId = useIdGenerator(\"\");\n return Object.entries(props).map(([key, value]) => {\n return <Property key={key} name={key} id={getId(key)} value={value} />;\n });\n};\n\ntype ExtensionReactComponentProps<TParamsSchema extends z.ZodTypeAny> = z.infer<TParamsSchema> & {\n remove?: boolean;\n before?: string;\n after?: string;\n name?: string;\n};\n\nexport function createExtensionReactComponent<TParamsSchema extends z.ZodTypeAny>(\n extensionParams: DefineExtensionParams<TParamsSchema>\n) {\n const ExtensionReactComponent: React.FC<\n ExtensionReactComponentProps<TParamsSchema>\n > = props => {\n // If custom render function is provided, use it.\n if (extensionParams.render) {\n return <>{extensionParams.render(props)}</>;\n }\n\n const { name, remove, before, after, ...keyValues } = props;\n\n const getId = useIdGenerator(extensionParams.type);\n\n // By passing undefined, we're letting RP generate a unique ID for us.\n const propertyId = useMemo(() => {\n if (extensionParams.multiple) {\n return name ? getId(name) : undefined;\n }\n\n return getId(extensionParams.type);\n }, [name, extensionParams.multiple, getId]);\n\n const propertyName = name || extensionParams.type;\n\n const placeAfter = after !== undefined ? getId(after) : undefined;\n const placeBefore = before !== undefined ? getId(before) : undefined;\n\n // @ts-expect-error move KeyValues back inside the Property component to avoid this error\n const KeyValuesComponent = parentProps => <KeyValues {...parentProps} {...keyValues} />;\n\n return (\n <Property\n id={propertyId}\n name={propertyName}\n array={extensionParams.multiple}\n remove={remove}\n before={placeBefore}\n after={placeAfter}\n >\n <KeyValuesComponent />\n </Property>\n );\n };\n\n ExtensionReactComponent.displayName = `ExtensionReactComponent(${extensionParams.type})`;\n return ExtensionReactComponent;\n}\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,OAAO,QAAQ,OAAO;AACtC,SAASC,QAAQ,EAAEC,cAAc,QAAQ,0BAA0B;AAInE,MAAMC,SAAS,GAAIC,KAA0B,IAAK;EAC9C,MAAMC,KAAK,GAAGH,cAAc,CAAC,EAAE,CAAC;EAChC,OAAOI,MAAM,CAACC,OAAO,CAACH,KAAK,CAAC,CAACI,GAAG,CAAC,CAAC,CAACC,GAAG,EAAEC,KAAK,CAAC,KAAK;IAC/C,oBAAOX,KAAA,CAAAY,aAAA,CAACV,QAAQ;MAACQ,GAAG,EAAEA,GAAI;MAACG,IAAI,EAAEH,GAAI;MAACI,EAAE,EAAER,KAAK,CAACI,GAAG,CAAE;MAACC,KAAK,EAAEA;IAAM,CAAE,CAAC;EAC1E,CAAC,CAAC;AACN,CAAC;AASD,OAAO,SAASI,6BAA6BA,CACzCC,eAAqD,EACvD;EACE,MAAMC,uBAEL,GAAGZ,KAAK,IAAI;IACT;IACA,IAAIW,eAAe,CAACE,MAAM,EAAE;MACxB,oBAAOlB,KAAA,CAAAY,aAAA,CAAAZ,KAAA,CAAAmB,QAAA,QAAGH,eAAe,CAACE,MAAM,CAACb,KAAK,CAAI,CAAC;IAC/C;IAEA,MAAM;MAAEQ,IAAI;MAAEO,MAAM;MAAEC,MAAM;MAAEC,KAAK;MAAE,GAAGC;IAAU,CAAC,GAAGlB,KAAK;IAE3D,MAAMC,KAAK,GAAGH,cAAc,CAACa,eAAe,CAACQ,IAAI,CAAC;;IAElD;IACA,MAAMC,UAAU,GAAGxB,OAAO,CAAC,MAAM;MAC7B,IAAIe,eAAe,CAACU,QAAQ,EAAE;QAC1B,OAAOb,IAAI,GAAGP,KAAK,CAACO,IAAI,CAAC,GAAGc,SAAS;MACzC;MAEA,OAAOrB,KAAK,CAACU,eAAe,CAACQ,IAAI,CAAC;IACtC,CAAC,EAAE,CAACX,IAAI,EAAEG,eAAe,CAACU,QAAQ,EAAEpB,KAAK,CAAC,CAAC;IAE3C,MAAMsB,YAAY,GAAGf,IAAI,IAAIG,eAAe,CAACQ,IAAI;IAEjD,MAAMK,UAAU,GAAGP,KAAK,KAAKK,SAAS,GAAGrB,KAAK,CAACgB,KAAK,CAAC,GAAGK,SAAS;IACjE,MAAMG,WAAW,GAAGT,MAAM,KAAKM,SAAS,GAAGrB,KAAK,CAACe,MAAM,CAAC,GAAGM,SAAS;;IAEpE;IACA,MAAMI,kBAAkB,GAAGC,WAAW,iBAAIhC,KAAA,CAAAY,aAAA,CAACR,SAAS,EAAAG,MAAA,CAAA0B,MAAA,KAAKD,WAAW,EAAMT,SAAS,CAAG,CAAC;IAEvF,oBACIvB,KAAA,CAAAY,aAAA,CAACV,QAAQ;MACLY,EAAE,EAAEW,UAAW;MACfZ,IAAI,EAAEe,YAAa;MACnBM,KAAK,EAAElB,eAAe,CAACU,QAAS;MAChCN,MAAM,EAAEA,MAAO;MACfC,MAAM,EAAES,WAAY;MACpBR,KAAK,EAAEO;IAAW,gBAElB7B,KAAA,CAAAY,aAAA,CAACmB,kBAAkB,MAAE,CACf,CAAC;EAEnB,CAAC;EAEDd,uBAAuB,CAACkB,WAAW,GAAG,2BAA2BnB,eAAe,CAACQ,IAAI,GAAG;EACxF,OAAOP,uBAAuB;AAClC","ignoreList":[]}
1
+ {"version":3,"names":["React","useMemo","Property","useIdGenerator","KeyValues","props","getId","Object","entries","map","key","value","createElement","name","id","createExtensionReactComponent","extensionParams","ExtensionReactComponent","remove","before","after","keyValues","type","propertyId","multiple","undefined","propertyName","placeAfter","placeBefore","KeyValuesComponent","parentProps","assign","Fragment","array","render","displayName"],"sources":["createExtensionReactComponent.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { Property, useIdGenerator } from \"@webiny/react-properties\";\nimport { type DefineExtensionParams } from \"./types.js\";\nimport { type z } from \"zod\";\n\nconst KeyValues = (props: Record<string, any>) => {\n const getId = useIdGenerator(\"\");\n return Object.entries(props).map(([key, value]) => {\n return <Property key={key} name={key} id={getId(key)} value={value} />;\n });\n};\n\ntype ExtensionReactComponentProps<TParamsSchema extends z.ZodTypeAny> = z.infer<TParamsSchema> & {\n remove?: boolean;\n before?: string;\n after?: string;\n name?: string;\n};\n\nexport function createExtensionReactComponent<TParamsSchema extends z.ZodTypeAny>(\n extensionParams: DefineExtensionParams<TParamsSchema>\n) {\n const ExtensionReactComponent: React.FC<\n ExtensionReactComponentProps<TParamsSchema>\n > = props => {\n const { name, remove, before, after, ...keyValues } = props;\n\n const getId = useIdGenerator(extensionParams.type);\n\n // By passing undefined, we're letting RP generate a unique ID for us.\n const propertyId = useMemo(() => {\n if (extensionParams.multiple) {\n return name ? getId(name) : undefined;\n }\n\n return getId(extensionParams.type);\n }, [name, extensionParams.multiple, getId]);\n\n const propertyName = name || extensionParams.type;\n\n const placeAfter = after !== undefined ? getId(after) : undefined;\n const placeBefore = before !== undefined ? getId(before) : undefined;\n\n // @ts-expect-error move KeyValues back inside the Property component to avoid this error\n const KeyValuesComponent = parentProps => <KeyValues {...parentProps} {...keyValues} />;\n\n return (\n <>\n <Property\n id={propertyId}\n name={propertyName}\n array={extensionParams.multiple}\n remove={remove}\n before={placeBefore}\n after={placeAfter}\n >\n <KeyValuesComponent />\n </Property>\n {extensionParams.render && extensionParams.render(props)}\n </>\n );\n };\n\n ExtensionReactComponent.displayName = `ExtensionReactComponent(${extensionParams.type})`;\n return ExtensionReactComponent;\n}\n"],"mappings":"AAAA,OAAOA,KAAK,IAAIC,OAAO,QAAQ,OAAO;AACtC,SAASC,QAAQ,EAAEC,cAAc,QAAQ,0BAA0B;AAInE,MAAMC,SAAS,GAAIC,KAA0B,IAAK;EAC9C,MAAMC,KAAK,GAAGH,cAAc,CAAC,EAAE,CAAC;EAChC,OAAOI,MAAM,CAACC,OAAO,CAACH,KAAK,CAAC,CAACI,GAAG,CAAC,CAAC,CAACC,GAAG,EAAEC,KAAK,CAAC,KAAK;IAC/C,oBAAOX,KAAA,CAAAY,aAAA,CAACV,QAAQ;MAACQ,GAAG,EAAEA,GAAI;MAACG,IAAI,EAAEH,GAAI;MAACI,EAAE,EAAER,KAAK,CAACI,GAAG,CAAE;MAACC,KAAK,EAAEA;IAAM,CAAE,CAAC;EAC1E,CAAC,CAAC;AACN,CAAC;AASD,OAAO,SAASI,6BAA6BA,CACzCC,eAAqD,EACvD;EACE,MAAMC,uBAEL,GAAGZ,KAAK,IAAI;IACT,MAAM;MAAEQ,IAAI;MAAEK,MAAM;MAAEC,MAAM;MAAEC,KAAK;MAAE,GAAGC;IAAU,CAAC,GAAGhB,KAAK;IAE3D,MAAMC,KAAK,GAAGH,cAAc,CAACa,eAAe,CAACM,IAAI,CAAC;;IAElD;IACA,MAAMC,UAAU,GAAGtB,OAAO,CAAC,MAAM;MAC7B,IAAIe,eAAe,CAACQ,QAAQ,EAAE;QAC1B,OAAOX,IAAI,GAAGP,KAAK,CAACO,IAAI,CAAC,GAAGY,SAAS;MACzC;MAEA,OAAOnB,KAAK,CAACU,eAAe,CAACM,IAAI,CAAC;IACtC,CAAC,EAAE,CAACT,IAAI,EAAEG,eAAe,CAACQ,QAAQ,EAAElB,KAAK,CAAC,CAAC;IAE3C,MAAMoB,YAAY,GAAGb,IAAI,IAAIG,eAAe,CAACM,IAAI;IAEjD,MAAMK,UAAU,GAAGP,KAAK,KAAKK,SAAS,GAAGnB,KAAK,CAACc,KAAK,CAAC,GAAGK,SAAS;IACjE,MAAMG,WAAW,GAAGT,MAAM,KAAKM,SAAS,GAAGnB,KAAK,CAACa,MAAM,CAAC,GAAGM,SAAS;;IAEpE;IACA,MAAMI,kBAAkB,GAAGC,WAAW,iBAAI9B,KAAA,CAAAY,aAAA,CAACR,SAAS,EAAAG,MAAA,CAAAwB,MAAA,KAAKD,WAAW,EAAMT,SAAS,CAAG,CAAC;IAEvF,oBACIrB,KAAA,CAAAY,aAAA,CAAAZ,KAAA,CAAAgC,QAAA,qBACIhC,KAAA,CAAAY,aAAA,CAACV,QAAQ;MACLY,EAAE,EAAES,UAAW;MACfV,IAAI,EAAEa,YAAa;MACnBO,KAAK,EAAEjB,eAAe,CAACQ,QAAS;MAChCN,MAAM,EAAEA,MAAO;MACfC,MAAM,EAAES,WAAY;MACpBR,KAAK,EAAEO;IAAW,gBAElB3B,KAAA,CAAAY,aAAA,CAACiB,kBAAkB,MAAE,CACf,CAAC,EACVb,eAAe,CAACkB,MAAM,IAAIlB,eAAe,CAACkB,MAAM,CAAC7B,KAAK,CACzD,CAAC;EAEX,CAAC;EAEDY,uBAAuB,CAACkB,WAAW,GAAG,2BAA2BnB,eAAe,CAACM,IAAI,GAAG;EACxF,OAAOL,uBAAuB;AAClC","ignoreList":[]}
@@ -1,4 +1,3 @@
1
1
  export * from "./defineExtension.js";
2
- export * from "./defineApiExtension.js";
3
2
  export * from "./models/index.js";
4
3
  export * from "./zodTypes/zodSrcPath.js";
@@ -1,5 +1,4 @@
1
1
  export * from "./defineExtension.js";
2
- export * from "./defineApiExtension.js";
3
2
  export * from "./models/index.js";
4
3
  export * from "./zodTypes/zodSrcPath.js";
5
4
 
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./defineExtension.js\";\nexport * from \"./defineApiExtension.js\";\nexport * from \"./models/index.js\";\nexport * from \"./zodTypes/zodSrcPath.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./defineExtension.js\";\nexport * from \"./models/index.js\";\nexport * from \"./zodTypes/zodSrcPath.js\";\n"],"mappings":"AAAA;AACA;AACA","ignoreList":[]}
@@ -4,6 +4,7 @@ import { type IProjectModel } from "../../abstractions/models/index.js";
4
4
  /**
5
5
  * TypeScript type for source paths.
6
6
  * - `/extensions/${string}` - resolves from project root
7
+ * - `@/${string}` or other tsconfig aliases - resolves using tsconfig.json paths
7
8
  * - string (absolute path) - treated as absolute path
8
9
  */
9
10
  export type SrcPath = `/extensions/${string}` | string;
@@ -1,13 +1,13 @@
1
1
  import { Metadata } from "@webiny/di";
2
2
  import { z } from "zod";
3
3
  import path from "path";
4
- import fs from "fs";
5
4
  import { ProjectError } from "../../ProjectError.js";
6
- import { ImplPathResolver } from "../../utils/index.js";
5
+ import { ExtensionSrcResolver } from "../../utils/index.js";
7
6
 
8
7
  /**
9
8
  * TypeScript type for source paths.
10
9
  * - `/extensions/${string}` - resolves from project root
10
+ * - `@/${string}` or other tsconfig aliases - resolves using tsconfig.json paths
11
11
  * - string (absolute path) - treated as absolute path
12
12
  */
13
13
 
@@ -21,18 +21,10 @@ export const zodSrcPath = options => {
21
21
  return str.replace(/^Symbol\(/, "").replace(/\)$/, "");
22
22
  };
23
23
  const tokenName = abstraction ? getTokenName(abstraction.token) : undefined;
24
- const description = abstraction ? `Path to a file exporting ${tokenName}. Use "/extensions/..." to resolve from project root, or provide an absolute path.` : `Path: "/extensions/..." resolves from project root, or provide an absolute path.`;
24
+ const description = abstraction ? `Path to a file exporting ${tokenName}. Use "/extensions/..." to resolve from project root, "@/..." for tsconfig path aliases, or provide an absolute path.` : `Path: "/extensions/..." resolves from project root, "@/..." resolves using tsconfig path aliases, or provide an absolute path.`;
25
25
  return z.string().describe(description).transform(val => val).superRefine(async (src, ctx) => {
26
- // Convert to absolute path for file existence check.
27
- let absoluteSrcPath;
28
- if (src.startsWith("/extensions/")) {
29
- // Resolve from project root.
30
- absoluteSrcPath = project.paths.rootFolder.join(src).toString();
31
- } else {
32
- // Treat as absolute path.
33
- absoluteSrcPath = src;
34
- }
35
- if (!fs.existsSync(absoluteSrcPath)) {
26
+ // Check if file exists using ExtensionSrcResolver.
27
+ if (!ExtensionSrcResolver.existsSync(src, project)) {
36
28
  ctx.addIssue({
37
29
  code: z.ZodIssueCode.custom,
38
30
  message: ProjectError.formatMessage(`File not found: %s. Please check the path and try again.`, src)
@@ -42,8 +34,9 @@ export const zodSrcPath = options => {
42
34
 
43
35
  // If abstraction validation is required
44
36
  if (abstraction) {
37
+ const absoluteSrcPath = ExtensionSrcResolver.resolvePath(src, project);
45
38
  const exportName = path.basename(absoluteSrcPath).replace(path.extname(absoluteSrcPath), "");
46
- const exportedImplementation = await ImplPathResolver.importFromPath(src, project);
39
+ const exportedImplementation = await ExtensionSrcResolver.importFromPath(src, project);
47
40
  if (!exportedImplementation) {
48
41
  ctx.addIssue({
49
42
  code: z.ZodIssueCode.custom,
@@ -1 +1 @@
1
- {"version":3,"names":["Metadata","z","path","fs","ProjectError","ImplPathResolver","zodSrcPath","options","project","abstraction","getTokenName","token","str","toString","replace","tokenName","undefined","description","string","describe","transform","val","superRefine","src","ctx","absoluteSrcPath","startsWith","paths","rootFolder","join","existsSync","addIssue","code","ZodIssueCode","custom","message","formatMessage","exportName","basename","extname","exportedImplementation","importFromPath","metadata","metadataName","getAbstraction","defName","isCorrectAbstraction"],"sources":["zodSrcPath.ts"],"sourcesContent":["import { type Abstraction, Metadata } from \"@webiny/di\";\nimport { z } from \"zod\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { type IProjectModel } from \"~/abstractions/models/index.js\";\nimport { ProjectError } from \"~/ProjectError.js\";\nimport { ImplPathResolver } from \"~/utils/index.js\";\n\n/**\n * TypeScript type for source paths.\n * - `/extensions/${string}` - resolves from project root\n * - string (absolute path) - treated as absolute path\n */\nexport type SrcPath = `/extensions/${string}` | string;\n\ntype ZodSrcPathOptions = {\n project: IProjectModel;\n abstraction?: Abstraction<any>;\n};\n\nexport const zodSrcPath = (options: ZodSrcPathOptions) => {\n const { project, abstraction } = options;\n\n const getTokenName = (token: symbol) => {\n const str = token.toString();\n return str.replace(/^Symbol\\(/, \"\").replace(/\\)$/, \"\");\n };\n\n const tokenName = abstraction ? getTokenName(abstraction.token) : undefined;\n const description = abstraction\n ? `Path to a file exporting ${tokenName}. Use \"/extensions/...\" to resolve from project root, or provide an absolute path.`\n : `Path: \"/extensions/...\" resolves from project root, or provide an absolute path.`;\n\n return z\n .string()\n .describe(description)\n .transform((val): SrcPath => val as SrcPath)\n .superRefine(async (src, ctx) => {\n // Convert to absolute path for file existence check.\n let absoluteSrcPath: string;\n if (src.startsWith(\"/extensions/\")) {\n // Resolve from project root.\n absoluteSrcPath = project.paths.rootFolder.join(src).toString();\n } else {\n // Treat as absolute path.\n absoluteSrcPath = src;\n }\n\n if (!fs.existsSync(absoluteSrcPath)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: ProjectError.formatMessage(\n `File not found: %s. Please check the path and try again.`,\n src\n )\n });\n return;\n }\n\n // If abstraction validation is required\n if (abstraction) {\n const exportName = path\n .basename(absoluteSrcPath)\n .replace(path.extname(absoluteSrcPath), \"\");\n\n const exportedImplementation = await ImplPathResolver.importFromPath(src, project);\n\n if (!exportedImplementation) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: ProjectError.formatMessage(\n `The file %s must export a class named %s or as a default export.`,\n src,\n exportName\n )\n });\n return;\n }\n\n const metadata = new Metadata(exportedImplementation);\n const metadataName = metadata.getAbstraction().toString();\n const defName = abstraction.toString();\n const isCorrectAbstraction = metadataName === defName;\n\n if (!isCorrectAbstraction) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: ProjectError.formatMessage(\n `The class %s in %s must implement the %s interface.`,\n exportName,\n src,\n tokenName || \"\"\n )\n });\n }\n }\n });\n};\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["Metadata","z","path","ProjectError","ExtensionSrcResolver","zodSrcPath","options","project","abstraction","getTokenName","token","str","toString","replace","tokenName","undefined","description","string","describe","transform","val","superRefine","src","ctx","existsSync","addIssue","code","ZodIssueCode","custom","message","formatMessage","absoluteSrcPath","resolvePath","exportName","basename","extname","exportedImplementation","importFromPath","metadata","metadataName","getAbstraction","defName","isCorrectAbstraction"],"sources":["zodSrcPath.ts"],"sourcesContent":["import { type Abstraction, Metadata } from \"@webiny/di\";\nimport { z } from \"zod\";\nimport path from \"path\";\nimport { type IProjectModel } from \"~/abstractions/models/index.js\";\nimport { ProjectError } from \"~/ProjectError.js\";\nimport { ExtensionSrcResolver } from \"~/utils/index.js\";\n\n/**\n * TypeScript type for source paths.\n * - `/extensions/${string}` - resolves from project root\n * - `@/${string}` or other tsconfig aliases - resolves using tsconfig.json paths\n * - string (absolute path) - treated as absolute path\n */\nexport type SrcPath = `/extensions/${string}` | string;\n\ntype ZodSrcPathOptions = {\n project: IProjectModel;\n abstraction?: Abstraction<any>;\n};\n\nexport const zodSrcPath = (options: ZodSrcPathOptions) => {\n const { project, abstraction } = options;\n\n const getTokenName = (token: symbol) => {\n const str = token.toString();\n return str.replace(/^Symbol\\(/, \"\").replace(/\\)$/, \"\");\n };\n\n const tokenName = abstraction ? getTokenName(abstraction.token) : undefined;\n const description = abstraction\n ? `Path to a file exporting ${tokenName}. Use \"/extensions/...\" to resolve from project root, \"@/...\" for tsconfig path aliases, or provide an absolute path.`\n : `Path: \"/extensions/...\" resolves from project root, \"@/...\" resolves using tsconfig path aliases, or provide an absolute path.`;\n\n return z\n .string()\n .describe(description)\n .transform((val): SrcPath => val as SrcPath)\n .superRefine(async (src, ctx) => {\n // Check if file exists using ExtensionSrcResolver.\n if (!ExtensionSrcResolver.existsSync(src, project)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: ProjectError.formatMessage(\n `File not found: %s. Please check the path and try again.`,\n src\n )\n });\n return;\n }\n\n // If abstraction validation is required\n if (abstraction) {\n const absoluteSrcPath = ExtensionSrcResolver.resolvePath(src, project);\n const exportName = path\n .basename(absoluteSrcPath)\n .replace(path.extname(absoluteSrcPath), \"\");\n\n const exportedImplementation = await ExtensionSrcResolver.importFromPath(\n src,\n project\n );\n\n if (!exportedImplementation) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: ProjectError.formatMessage(\n `The file %s must export a class named %s or as a default export.`,\n src,\n exportName\n )\n });\n return;\n }\n\n const metadata = new Metadata(exportedImplementation);\n const metadataName = metadata.getAbstraction().toString();\n const defName = abstraction.toString();\n const isCorrectAbstraction = metadataName === defName;\n\n if (!isCorrectAbstraction) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: ProjectError.formatMessage(\n `The class %s in %s must implement the %s interface.`,\n exportName,\n src,\n tokenName || \"\"\n )\n });\n }\n }\n });\n};\n"],"mappings":"AAAA,SAA2BA,QAAQ,QAAQ,YAAY;AACvD,SAASC,CAAC,QAAQ,KAAK;AACvB,OAAOC,IAAI,MAAM,MAAM;AAEvB,SAASC,YAAY;AACrB,SAASC,oBAAoB;;AAE7B;AACA;AACA;AACA;AACA;AACA;;AAQA,OAAO,MAAMC,UAAU,GAAIC,OAA0B,IAAK;EACtD,MAAM;IAAEC,OAAO;IAAEC;EAAY,CAAC,GAAGF,OAAO;EAExC,MAAMG,YAAY,GAAIC,KAAa,IAAK;IACpC,MAAMC,GAAG,GAAGD,KAAK,CAACE,QAAQ,CAAC,CAAC;IAC5B,OAAOD,GAAG,CAACE,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAACA,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;EAC1D,CAAC;EAED,MAAMC,SAAS,GAAGN,WAAW,GAAGC,YAAY,CAACD,WAAW,CAACE,KAAK,CAAC,GAAGK,SAAS;EAC3E,MAAMC,WAAW,GAAGR,WAAW,GACzB,4BAA4BM,SAAS,uHAAuH,GAC5J,gIAAgI;EAEtI,OAAOb,CAAC,CACHgB,MAAM,CAAC,CAAC,CACRC,QAAQ,CAACF,WAAW,CAAC,CACrBG,SAAS,CAAEC,GAAG,IAAcA,GAAc,CAAC,CAC3CC,WAAW,CAAC,OAAOC,GAAG,EAAEC,GAAG,KAAK;IAC7B;IACA,IAAI,CAACnB,oBAAoB,CAACoB,UAAU,CAACF,GAAG,EAAEf,OAAO,CAAC,EAAE;MAChDgB,GAAG,CAACE,QAAQ,CAAC;QACTC,IAAI,EAAEzB,CAAC,CAAC0B,YAAY,CAACC,MAAM;QAC3BC,OAAO,EAAE1B,YAAY,CAAC2B,aAAa,CAC/B,0DAA0D,EAC1DR,GACJ;MACJ,CAAC,CAAC;MACF;IACJ;;IAEA;IACA,IAAId,WAAW,EAAE;MACb,MAAMuB,eAAe,GAAG3B,oBAAoB,CAAC4B,WAAW,CAACV,GAAG,EAAEf,OAAO,CAAC;MACtE,MAAM0B,UAAU,GAAG/B,IAAI,CAClBgC,QAAQ,CAACH,eAAe,CAAC,CACzBlB,OAAO,CAACX,IAAI,CAACiC,OAAO,CAACJ,eAAe,CAAC,EAAE,EAAE,CAAC;MAE/C,MAAMK,sBAAsB,GAAG,MAAMhC,oBAAoB,CAACiC,cAAc,CACpEf,GAAG,EACHf,OACJ,CAAC;MAED,IAAI,CAAC6B,sBAAsB,EAAE;QACzBb,GAAG,CAACE,QAAQ,CAAC;UACTC,IAAI,EAAEzB,CAAC,CAAC0B,YAAY,CAACC,MAAM;UAC3BC,OAAO,EAAE1B,YAAY,CAAC2B,aAAa,CAC/B,kEAAkE,EAClER,GAAG,EACHW,UACJ;QACJ,CAAC,CAAC;QACF;MACJ;MAEA,MAAMK,QAAQ,GAAG,IAAItC,QAAQ,CAACoC,sBAAsB,CAAC;MACrD,MAAMG,YAAY,GAAGD,QAAQ,CAACE,cAAc,CAAC,CAAC,CAAC5B,QAAQ,CAAC,CAAC;MACzD,MAAM6B,OAAO,GAAGjC,WAAW,CAACI,QAAQ,CAAC,CAAC;MACtC,MAAM8B,oBAAoB,GAAGH,YAAY,KAAKE,OAAO;MAErD,IAAI,CAACC,oBAAoB,EAAE;QACvBnB,GAAG,CAACE,QAAQ,CAAC;UACTC,IAAI,EAAEzB,CAAC,CAAC0B,YAAY,CAACC,MAAM;UAC3BC,OAAO,EAAE1B,YAAY,CAAC2B,aAAa,CAC/B,qDAAqD,EACrDG,UAAU,EACVX,GAAG,EACHR,SAAS,IAAI,EACjB;QACJ,CAAC,CAAC;MACN;IACJ;EACJ,CAAC,CAAC;AACV,CAAC","ignoreList":[]}
@@ -5,4 +5,4 @@ export { BeforeBuild as BeforeBuildHook } from "../../abstractions/features/hook
5
5
  export { AfterDeploy as AfterDeployHook } from "../../abstractions/features/hooks/AfterDeploy.js";
6
6
  export { BeforeDeploy as BeforeDeployHook } from "../../abstractions/features/hooks/BeforeDeploy.js";
7
7
  export { BeforeWatch as BeforeWatchHook } from "../../abstractions/features/hooks/BeforeWatch.js";
8
- export { GetAppStackOutput } from "../../abstractions/features/GetAppStackOutput.js";
8
+ export { EnvVar } from "../../extensions/EnvVar.js";
@@ -5,6 +5,6 @@ export { BeforeBuild as BeforeBuildHook } from "../../abstractions/features/hook
5
5
  export { AfterDeploy as AfterDeployHook } from "../../abstractions/features/hooks/AfterDeploy.js";
6
6
  export { BeforeDeploy as BeforeDeployHook } from "../../abstractions/features/hooks/BeforeDeploy.js";
7
7
  export { BeforeWatch as BeforeWatchHook } from "../../abstractions/features/hooks/BeforeWatch.js";
8
- export { GetAppStackOutput } from "../../abstractions/features/GetAppStackOutput.js";
8
+ export { EnvVar } from "../../extensions/EnvVar.js";
9
9
 
10
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["LoggerService","Logger","UiService","Ui","AfterBuild","AfterBuildHook","BeforeBuild","BeforeBuildHook","AfterDeploy","AfterDeployHook","BeforeDeploy","BeforeDeployHook","BeforeWatch","BeforeWatchHook","GetAppStackOutput"],"sources":["index.ts"],"sourcesContent":["export { LoggerService as Logger } from \"~/abstractions/services/LoggerService.js\";\nexport { UiService as Ui } from \"~/abstractions/services/UiService.js\";\nexport { AfterBuild as AfterBuildHook } from \"~/abstractions/features/hooks/AfterBuild.js\";\nexport { BeforeBuild as BeforeBuildHook } from \"~/abstractions/features/hooks/BeforeBuild.js\";\nexport { AfterDeploy as AfterDeployHook } from \"~/abstractions/features/hooks/AfterDeploy.js\";\nexport { BeforeDeploy as BeforeDeployHook } from \"~/abstractions/features/hooks/BeforeDeploy.js\";\nexport { BeforeWatch as BeforeWatchHook } from \"~/abstractions/features/hooks/BeforeWatch.js\";\nexport { GetAppStackOutput } from \"~/abstractions/features/GetAppStackOutput.js\";\n"],"mappings":"AAAA,SAASA,aAAa,IAAIC,MAAM;AAChC,SAASC,SAAS,IAAIC,EAAE;AACxB,SAASC,UAAU,IAAIC,cAAc;AACrC,SAASC,WAAW,IAAIC,eAAe;AACvC,SAASC,WAAW,IAAIC,eAAe;AACvC,SAASC,YAAY,IAAIC,gBAAgB;AACzC,SAASC,WAAW,IAAIC,eAAe;AACvC,SAASC,iBAAiB","ignoreList":[]}
1
+ {"version":3,"names":["LoggerService","Logger","UiService","Ui","AfterBuild","AfterBuildHook","BeforeBuild","BeforeBuildHook","AfterDeploy","AfterDeployHook","BeforeDeploy","BeforeDeployHook","BeforeWatch","BeforeWatchHook","EnvVar"],"sources":["index.ts"],"sourcesContent":["export { LoggerService as Logger } from \"~/abstractions/services/LoggerService.js\";\nexport { UiService as Ui } from \"~/abstractions/services/UiService.js\";\nexport { AfterBuild as AfterBuildHook } from \"~/abstractions/features/hooks/AfterBuild.js\";\nexport { BeforeBuild as BeforeBuildHook } from \"~/abstractions/features/hooks/BeforeBuild.js\";\nexport { AfterDeploy as AfterDeployHook } from \"~/abstractions/features/hooks/AfterDeploy.js\";\nexport { BeforeDeploy as BeforeDeployHook } from \"~/abstractions/features/hooks/BeforeDeploy.js\";\nexport { BeforeWatch as BeforeWatchHook } from \"~/abstractions/features/hooks/BeforeWatch.js\";\nexport { EnvVar } from \"~/extensions/EnvVar.js\";\n"],"mappings":"AAAA,SAASA,aAAa,IAAIC,MAAM;AAChC,SAASC,SAAS,IAAIC,EAAE;AACxB,SAASC,UAAU,IAAIC,cAAc;AACrC,SAASC,WAAW,IAAIC,eAAe;AACvC,SAASC,WAAW,IAAIC,eAAe;AACvC,SAASC,YAAY,IAAIC,gBAAgB;AACzC,SAASC,WAAW,IAAIC,eAAe;AACvC,SAASC,MAAM","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import { z } from "zod";
2
+ export declare const AdminBuildParam: import("~/defineExtension/index.js").ExtensionComponent<z.ZodObject<{
3
+ paramName: z.ZodString;
4
+ value: z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodAny>, z.ZodArray<z.ZodAny, "many">, z.ZodNumber, z.ZodBoolean]>;
5
+ }, "strip", z.ZodTypeAny, {
6
+ value: string | number | boolean | any[] | Record<string, any>;
7
+ paramName: string;
8
+ }, {
9
+ value: string | number | boolean | any[] | Record<string, any>;
10
+ paramName: string;
11
+ }>>;
@@ -0,0 +1,184 @@
1
+ import { z } from "zod";
2
+ import { defineExtension } from "../defineExtension/index.js";
3
+ import crypto from "crypto";
4
+ import path from "path";
5
+ import fs from "fs";
6
+ import { Node, Project } from "ts-morph";
7
+ async function generateBuildParamsFeature(buildParamsDir, ctx) {
8
+ const featureFilePath = path.join(buildParamsDir, "feature.ts");
9
+
10
+ // Get all BuildParam_*.ts files.
11
+ const files = fs.readdirSync(buildParamsDir).filter(f => f.startsWith("BuildParam_") && f.endsWith(".ts") && f !== "feature.ts");
12
+
13
+ // Generate imports and registrations.
14
+ const imports = files.map(file => {
15
+ const className = path.parse(file).name;
16
+ return `import ${className} from "./${className}.js";`;
17
+ }).join("\n");
18
+ const registrations = files.map(file => {
19
+ const className = path.parse(file).name;
20
+ return ` container.register(${className});`;
21
+ }).join("\n");
22
+ const featureContent = `import { createFeature } from "@webiny/feature/admin";
23
+ import { Container } from "@webiny/di";
24
+ ${imports}
25
+
26
+ export const BuildParamsInternalFeature = createFeature({
27
+ name: "BuildParamsInternal",
28
+ register(container: Container) {
29
+ ${registrations}
30
+ }
31
+ });
32
+ `;
33
+ fs.writeFileSync(featureFilePath, featureContent, "utf8");
34
+
35
+ // Now we need to update Extensions.tsx to use RegisterFeature with this feature.
36
+ await updateExtensionsTsx(ctx);
37
+ }
38
+ async function updateExtensionsTsx(ctx) {
39
+ const extensionsTsxFilePath = ctx.project.paths.workspaceFolder.join("apps", "admin", "src", "Extensions.tsx").toString();
40
+ const project = new Project();
41
+ project.addSourceFileAtPath(extensionsTsxFilePath);
42
+ const source = project.getSourceFileOrThrow(extensionsTsxFilePath);
43
+
44
+ // Check if we already have the imports.
45
+ const buildParamsFeatureImport = "./buildParams/feature.js";
46
+ const existingFeatureImport = source.getImportDeclaration(buildParamsFeatureImport);
47
+ if (!existingFeatureImport) {
48
+ let index = 1;
49
+ const importDeclarations = source.getImportDeclarations();
50
+ if (importDeclarations.length) {
51
+ const last = importDeclarations[importDeclarations.length - 1];
52
+ index = last.getChildIndex() + 1;
53
+ }
54
+
55
+ // Add import for BuildParamsInternalFeature.
56
+ source.insertImportDeclaration(index, {
57
+ namedImports: ["BuildParamsInternalFeature"],
58
+ moduleSpecifier: buildParamsFeatureImport
59
+ });
60
+
61
+ // Add import for BuildParamsFeature.
62
+ const buildParamsFeatureImportPath = "@webiny/app-admin";
63
+ const existingBuildParamsImport = source.getImportDeclaration(buildParamsFeatureImportPath);
64
+ if (!existingBuildParamsImport) {
65
+ source.insertImportDeclaration(index, {
66
+ namedImports: ["BuildParamsFeature"],
67
+ moduleSpecifier: buildParamsFeatureImportPath
68
+ });
69
+ } else {
70
+ // Add to existing import if BuildParamsFeature not already there.
71
+ const namedImports = existingBuildParamsImport.getNamedImports();
72
+ const hasBuildParamsFeature = namedImports.some(ni => ni.getName() === "BuildParamsFeature");
73
+ if (!hasBuildParamsFeature) {
74
+ existingBuildParamsImport.addNamedImport("BuildParamsFeature");
75
+ }
76
+ }
77
+
78
+ // Add import for RegisterFeature if not present.
79
+ const registerFeatureImportPath = "@webiny/app-admin";
80
+ const existingRegisterFeatureImport = source.getImportDeclaration(registerFeatureImportPath);
81
+ if (existingRegisterFeatureImport) {
82
+ const namedImports = existingRegisterFeatureImport.getNamedImports();
83
+ const hasRegisterFeature = namedImports.some(ni => ni.getName() === "RegisterFeature");
84
+ if (!hasRegisterFeature) {
85
+ existingRegisterFeatureImport.addNamedImport("RegisterFeature");
86
+ }
87
+ } else {
88
+ source.insertImportDeclaration(index, {
89
+ namedImports: ["RegisterFeature"],
90
+ moduleSpecifier: registerFeatureImportPath
91
+ });
92
+ }
93
+ }
94
+
95
+ // Now add <RegisterFeature> components to the Extensions component.
96
+ const extensionsIdentifier = source.getFirstDescendant(node => {
97
+ if (!Node.isIdentifier(node)) {
98
+ return false;
99
+ }
100
+ return node.getText() === "Extensions";
101
+ });
102
+ if (!extensionsIdentifier) {
103
+ throw new Error(`Could not find the "Extensions" React component in "${extensionsTsxFilePath}".`);
104
+ }
105
+ const extensionsArrowFn = extensionsIdentifier.getNextSibling(node => Node.isArrowFunction(node));
106
+ if (!extensionsArrowFn) {
107
+ throw new Error(`Could not find the "Extensions" React component arrow function.`);
108
+ }
109
+ const extensionsArrowFnFragment = extensionsArrowFn.getFirstDescendant(node => {
110
+ return Node.isJsxFragment(node);
111
+ });
112
+ if (!extensionsArrowFnFragment) {
113
+ throw new Error(`Could not find JSX fragment in Extensions component.`);
114
+ }
115
+ const currentContent = extensionsArrowFnFragment.getFullText().replace("<>", "").replace("</>", "").trim();
116
+
117
+ // Check if we already have the RegisterFeature components.
118
+ if (!currentContent.includes("BuildParamsFeature")) {
119
+ const newContent = `<><RegisterFeature feature={BuildParamsFeature} /><RegisterFeature feature={BuildParamsInternalFeature} />${currentContent}</>`;
120
+ extensionsArrowFnFragment.replaceWithText(newContent);
121
+ }
122
+ await source.save();
123
+ }
124
+ export const AdminBuildParam = defineExtension({
125
+ type: "Admin/BuildParam",
126
+ tags: {
127
+ runtimeContext: "app-build",
128
+ appName: "admin"
129
+ },
130
+ description: "Add build-time parameter to Admin app.",
131
+ multiple: true,
132
+ paramsSchema: () => {
133
+ return z.object({
134
+ paramName: z.string(),
135
+ value: z.union([z.string(), z.record(z.any()), z.array(z.any()), z.number(), z.boolean()])
136
+ });
137
+ },
138
+ async build(params, ctx) {
139
+ const buildParamsDir = ctx.project.paths.workspaceFolder.join("apps", "admin", "src", "buildParams").toString();
140
+ const {
141
+ paramName,
142
+ value
143
+ } = params;
144
+
145
+ // Serialize value to a TypeScript literal.
146
+ const valueStr = JSON.stringify(value, null, 4);
147
+
148
+ // Generate a unique class name based on the paramName.
149
+ const hash = crypto.createHash("sha256").update(paramName).digest("hex");
150
+ const className = `BuildParam_${hash.slice(-10)}`;
151
+ const fileName = `${className}.ts`;
152
+ const filePath = path.join(buildParamsDir, fileName);
153
+
154
+ // Ensure buildParams directory exists.
155
+ if (!fs.existsSync(buildParamsDir)) {
156
+ fs.mkdirSync(buildParamsDir, {
157
+ recursive: true
158
+ });
159
+ }
160
+
161
+ // Check if file already exists.
162
+ if (!fs.existsSync(filePath)) {
163
+ // Create the BuildParam implementation file.
164
+ const fileContent = `import { BuildParam } from "webiny/admin/build-params";
165
+
166
+ class ${className} implements BuildParam.Interface {
167
+ key = "${paramName}";
168
+ value = ${valueStr};
169
+ }
170
+
171
+ export default BuildParam.createImplementation({
172
+ implementation: ${className},
173
+ dependencies: []
174
+ });
175
+ `;
176
+ fs.writeFileSync(filePath, fileContent, "utf8");
177
+ }
178
+
179
+ // Now we need to generate/update the feature file that imports all BuildParams.
180
+ await generateBuildParamsFeature(buildParamsDir, ctx);
181
+ }
182
+ });
183
+
184
+ //# sourceMappingURL=AdminBuildParam.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["z","defineExtension","crypto","path","fs","Node","Project","generateBuildParamsFeature","buildParamsDir","ctx","featureFilePath","join","files","readdirSync","filter","f","startsWith","endsWith","imports","map","file","className","parse","name","registrations","featureContent","writeFileSync","updateExtensionsTsx","extensionsTsxFilePath","project","paths","workspaceFolder","toString","addSourceFileAtPath","source","getSourceFileOrThrow","buildParamsFeatureImport","existingFeatureImport","getImportDeclaration","index","importDeclarations","getImportDeclarations","length","last","getChildIndex","insertImportDeclaration","namedImports","moduleSpecifier","buildParamsFeatureImportPath","existingBuildParamsImport","getNamedImports","hasBuildParamsFeature","some","ni","getName","addNamedImport","registerFeatureImportPath","existingRegisterFeatureImport","hasRegisterFeature","extensionsIdentifier","getFirstDescendant","node","isIdentifier","getText","Error","extensionsArrowFn","getNextSibling","isArrowFunction","extensionsArrowFnFragment","isJsxFragment","currentContent","getFullText","replace","trim","includes","newContent","replaceWithText","save","AdminBuildParam","type","tags","runtimeContext","appName","description","multiple","paramsSchema","object","paramName","string","value","union","record","any","array","number","boolean","build","params","valueStr","JSON","stringify","hash","createHash","update","digest","slice","fileName","filePath","existsSync","mkdirSync","recursive","fileContent"],"sources":["AdminBuildParam.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { defineExtension } from \"~/defineExtension/index.js\";\nimport crypto from \"crypto\";\nimport path from \"path\";\nimport fs from \"fs\";\nimport { Node, Project } from \"ts-morph\";\n\nasync function generateBuildParamsFeature(buildParamsDir: string, ctx: any) {\n const featureFilePath = path.join(buildParamsDir, \"feature.ts\");\n\n // Get all BuildParam_*.ts files.\n const files = fs\n .readdirSync(buildParamsDir)\n .filter(f => f.startsWith(\"BuildParam_\") && f.endsWith(\".ts\") && f !== \"feature.ts\");\n\n // Generate imports and registrations.\n const imports = files\n .map(file => {\n const className = path.parse(file).name;\n return `import ${className} from \"./${className}.js\";`;\n })\n .join(\"\\n\");\n\n const registrations = files\n .map(file => {\n const className = path.parse(file).name;\n return ` container.register(${className});`;\n })\n .join(\"\\n\");\n\n const featureContent = `import { createFeature } from \"@webiny/feature/admin\";\nimport { Container } from \"@webiny/di\";\n${imports}\n\nexport const BuildParamsInternalFeature = createFeature({\n name: \"BuildParamsInternal\",\n register(container: Container) {\n${registrations}\n }\n});\n`;\n\n fs.writeFileSync(featureFilePath, featureContent, \"utf8\");\n\n // Now we need to update Extensions.tsx to use RegisterFeature with this feature.\n await updateExtensionsTsx(ctx);\n}\n\nasync function updateExtensionsTsx(ctx: any) {\n const extensionsTsxFilePath = ctx.project.paths.workspaceFolder\n .join(\"apps\", \"admin\", \"src\", \"Extensions.tsx\")\n .toString();\n\n const project = new Project();\n project.addSourceFileAtPath(extensionsTsxFilePath);\n\n const source = project.getSourceFileOrThrow(extensionsTsxFilePath);\n\n // Check if we already have the imports.\n const buildParamsFeatureImport = \"./buildParams/feature.js\";\n const existingFeatureImport = source.getImportDeclaration(buildParamsFeatureImport);\n\n if (!existingFeatureImport) {\n let index = 1;\n const importDeclarations = source.getImportDeclarations();\n if (importDeclarations.length) {\n const last = importDeclarations[importDeclarations.length - 1];\n index = last.getChildIndex() + 1;\n }\n\n // Add import for BuildParamsInternalFeature.\n source.insertImportDeclaration(index, {\n namedImports: [\"BuildParamsInternalFeature\"],\n moduleSpecifier: buildParamsFeatureImport\n });\n\n // Add import for BuildParamsFeature.\n const buildParamsFeatureImportPath = \"@webiny/app-admin\";\n const existingBuildParamsImport = source.getImportDeclaration(buildParamsFeatureImportPath);\n\n if (!existingBuildParamsImport) {\n source.insertImportDeclaration(index, {\n namedImports: [\"BuildParamsFeature\"],\n moduleSpecifier: buildParamsFeatureImportPath\n });\n } else {\n // Add to existing import if BuildParamsFeature not already there.\n const namedImports = existingBuildParamsImport.getNamedImports();\n const hasBuildParamsFeature = namedImports.some(\n ni => ni.getName() === \"BuildParamsFeature\"\n );\n if (!hasBuildParamsFeature) {\n existingBuildParamsImport.addNamedImport(\"BuildParamsFeature\");\n }\n }\n\n // Add import for RegisterFeature if not present.\n const registerFeatureImportPath = \"@webiny/app-admin\";\n const existingRegisterFeatureImport =\n source.getImportDeclaration(registerFeatureImportPath);\n\n if (existingRegisterFeatureImport) {\n const namedImports = existingRegisterFeatureImport.getNamedImports();\n const hasRegisterFeature = namedImports.some(ni => ni.getName() === \"RegisterFeature\");\n if (!hasRegisterFeature) {\n existingRegisterFeatureImport.addNamedImport(\"RegisterFeature\");\n }\n } else {\n source.insertImportDeclaration(index, {\n namedImports: [\"RegisterFeature\"],\n moduleSpecifier: registerFeatureImportPath\n });\n }\n }\n\n // Now add <RegisterFeature> components to the Extensions component.\n const extensionsIdentifier = source.getFirstDescendant(node => {\n if (!Node.isIdentifier(node)) {\n return false;\n }\n return node.getText() === \"Extensions\";\n });\n\n if (!extensionsIdentifier) {\n throw new Error(\n `Could not find the \"Extensions\" React component in \"${extensionsTsxFilePath}\".`\n );\n }\n\n const extensionsArrowFn = extensionsIdentifier.getNextSibling(node =>\n Node.isArrowFunction(node)\n );\n\n if (!extensionsArrowFn) {\n throw new Error(`Could not find the \"Extensions\" React component arrow function.`);\n }\n\n const extensionsArrowFnFragment = extensionsArrowFn.getFirstDescendant(node => {\n return Node.isJsxFragment(node);\n });\n\n if (!extensionsArrowFnFragment) {\n throw new Error(`Could not find JSX fragment in Extensions component.`);\n }\n\n const currentContent = extensionsArrowFnFragment\n .getFullText()\n .replace(\"<>\", \"\")\n .replace(\"</>\", \"\")\n .trim();\n\n // Check if we already have the RegisterFeature components.\n if (!currentContent.includes(\"BuildParamsFeature\")) {\n const newContent = `<><RegisterFeature feature={BuildParamsFeature} /><RegisterFeature feature={BuildParamsInternalFeature} />${currentContent}</>`;\n extensionsArrowFnFragment.replaceWithText(newContent);\n }\n\n await source.save();\n}\n\nexport const AdminBuildParam = defineExtension({\n type: \"Admin/BuildParam\",\n tags: { runtimeContext: \"app-build\", appName: \"admin\" },\n description: \"Add build-time parameter to Admin app.\",\n multiple: true,\n paramsSchema: () => {\n return z.object({\n paramName: z.string(),\n value: z.union([\n z.string(),\n z.record(z.any()),\n z.array(z.any()),\n z.number(),\n z.boolean()\n ])\n });\n },\n async build(params, ctx) {\n const buildParamsDir = ctx.project.paths.workspaceFolder\n .join(\"apps\", \"admin\", \"src\", \"buildParams\")\n .toString();\n\n const { paramName, value } = params;\n\n // Serialize value to a TypeScript literal.\n const valueStr = JSON.stringify(value, null, 4);\n\n // Generate a unique class name based on the paramName.\n const hash = crypto.createHash(\"sha256\").update(paramName).digest(\"hex\");\n const className = `BuildParam_${hash.slice(-10)}`;\n const fileName = `${className}.ts`;\n const filePath = path.join(buildParamsDir, fileName);\n\n // Ensure buildParams directory exists.\n if (!fs.existsSync(buildParamsDir)) {\n fs.mkdirSync(buildParamsDir, { recursive: true });\n }\n\n // Check if file already exists.\n if (!fs.existsSync(filePath)) {\n // Create the BuildParam implementation file.\n const fileContent = `import { BuildParam } from \"webiny/admin/build-params\";\n\nclass ${className} implements BuildParam.Interface {\n key = \"${paramName}\";\n value = ${valueStr};\n}\n\nexport default BuildParam.createImplementation({\n implementation: ${className},\n dependencies: []\n});\n`;\n fs.writeFileSync(filePath, fileContent, \"utf8\");\n }\n\n // Now we need to generate/update the feature file that imports all BuildParams.\n await generateBuildParamsFeature(buildParamsDir, ctx);\n }\n});\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import { z } from "zod";
2
+ export declare const AdminExtension: import("~/extensions/index.js").ExtensionComponent<z.ZodObject<{
3
+ src: z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
4
+ exportName: z.ZodOptional<z.ZodString>;
5
+ }, "strip", z.ZodTypeAny, {
6
+ src: string;
7
+ exportName?: string | undefined;
8
+ }, {
9
+ src: string;
10
+ exportName?: string | undefined;
11
+ }>>;