@adobe/aio-commerce-lib-app 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/LICENSE +201 -0
- package/README.md +22 -0
- package/dist/cjs/commands/generate/actions/templates/get-app-config.js.template +61 -0
- package/dist/cjs/commands/index.cjs +144 -0
- package/dist/cjs/commands/index.d.cts +1 -0
- package/dist/cjs/config/index.cjs +14 -0
- package/dist/cjs/config/index.d.cts +995 -0
- package/dist/cjs/parser-DsI4Y-Z2.cjs +14 -0
- package/dist/es/commands/generate/actions/templates/get-app-config.js.template +61 -0
- package/dist/es/commands/index.d.mts +1 -0
- package/dist/es/commands/index.mjs +144 -0
- package/dist/es/config/index.d.mts +995 -0
- package/dist/es/config/index.mjs +14 -0
- package/dist/es/parser-BoZ6cYn-.mjs +14 -0
- package/package.json +77 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
5
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
7
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
11
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
import{a as validateCommerceAppConfig,i as resolveCommerceAppConfig,n as readBundledCommerceAppConfig,o as validateCommerceAppConfigDomain,r as readCommerceAppConfig,t as parseCommerceAppConfig}from"../parser-BoZ6cYn-.mjs";function defineConfig(config){return config}export{defineConfig,parseCommerceAppConfig,readBundledCommerceAppConfig,readCommerceAppConfig,resolveCommerceAppConfig,validateCommerceAppConfig,validateCommerceAppConfigDomain};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
5
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
7
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
11
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*/
|
|
14
|
+
import{access,mkdir,readFile}from"fs/promises";import{dirname,join,parse}from"path";import{CommerceSdkValidationError}from"@adobe/aio-commerce-lib-core/error";import{existsSync}from"fs";import{createJiti}from"jiti";import*as v from"valibot";function stringifyError(error){return error instanceof CommerceSdkValidationError?error.display():error instanceof Error?error.message:String(error)}async function findUp(name,options={}){let names=Array.isArray(name)?name:[name],cwd=options.cwd||process.cwd(),{root}=parse(cwd),stopAt=options.stopAt||root,currentDir=cwd;for(;;){for(let fileName of names){let filePath=join(currentDir,fileName);try{return await access(filePath),filePath}catch{}}if(currentDir===stopAt||currentDir===root)return;currentDir=dirname(currentDir)}}async function findNearestPackageJson(cwd=process.cwd()){return await findUp(`package.json`,{cwd})||null}async function getProjectRootDirectory(cwd=process.cwd()){let packageJsonPath=await findNearestPackageJson(cwd);if(!packageJsonPath)throw Error("Could not find a the root directory of the project. `package.json` file not found.");return dirname(packageJsonPath)}async function makeOutputDirFor(fileOrFolder){let outputDir=join(await getProjectRootDirectory(),fileOrFolder);return existsSync(outputDir)||await mkdir(outputDir,{recursive:!0}),outputDir}async function detectPackageManager(cwd=process.cwd()){let rootDirectory=await getProjectRootDirectory(cwd),lockFileMap={"bun.lockb":`bun`,"pnpm-lock.yaml":`pnpm`,"yarn.lock":`yarn`,"package-lock.json":`npm`},lockFileName=Object.keys(lockFileMap).find(name=>existsSync(join(rootDirectory,name)));return lockFileName?lockFileMap[lockFileName]:`npm`}function getExecCommand(packageManager){return{pnpm:`pnpx`,yarn:`yarn dlx`,bun:`bunx`,npm:`npx`}[packageManager]}const BaseOptionSchema=v.object({name:v.pipe(v.string(`Expected a string for the field name`),v.nonEmpty(`The field name must not be empty`)),label:v.optional(v.string(`Expected a string for the field label`)),description:v.optional(v.string(`Expected a string for the field description`))}),ListOptionSchema=v.object({label:v.string(`Expected a string for the option label`),value:v.string(`Expected a string for the option value`)}),SingleListSchema=v.object({...BaseOptionSchema.entries,type:v.literal(`list`,`Expected the type to be 'list'`),selectionMode:v.literal(`single`,`Expected the selectionMode to be 'single'`),options:v.array(ListOptionSchema,`Expected an array of list options`),default:v.pipe(v.string(`Expected a string for the default value`),v.nonEmpty(`The default value must not be empty`))}),MultipleListSchema=v.object({...BaseOptionSchema.entries,type:v.literal(`list`,`Expected the type to be 'list'`),selectionMode:v.literal(`multiple`,`Expected the selectionMode to be 'multiple'`),options:v.array(ListOptionSchema,`Expected an array of list options`),default:v.optional(v.array(v.pipe(v.string(`Expected a string for each default value`),v.nonEmpty(`Each default value must not be empty`)),`Expected an array of default values`),[])}),ListSchema=v.variant(`selectionMode`,[SingleListSchema,MultipleListSchema]),TextSchema=v.object({...BaseOptionSchema.entries,type:v.literal(`text`,`Expected the type to be 'text'`),default:v.optional(v.string(`Expected a string for the default value`))}),PasswordSchema=v.object({...BaseOptionSchema.entries,type:v.literal(`password`,`Expected the type to be 'password'`),default:v.optional(v.string(`Expected a string for the default value`))}),EmailSchema=v.object({...BaseOptionSchema.entries,type:v.literal(`email`,`Expected the type to be 'email'`),default:v.optional(v.pipe(v.string(`Expected a string for the default email value`),v.email(`The email must be a valid email address`)))}),UrlSchema=v.object({...BaseOptionSchema.entries,type:v.literal(`url`,`Expected the type to be 'url'`),default:v.optional(v.pipe(v.string(`Expected a string for the default URL value`),v.url(`The URL must be a valid URL`)))}),PhoneSchema=v.object({...BaseOptionSchema.entries,type:v.literal(`tel`,`Expected the type to be 'tel'`),default:v.optional(v.pipe(v.string(`Expected a string for the default phone number value`),v.regex(/^\+?[0-9\s\-()]+$/,`The phone number must contain only numbers and/or country codes`)))}),FieldSchema=v.variant(`type`,[ListSchema,TextSchema,PasswordSchema,EmailSchema,UrlSchema,PhoneSchema]),SchemaBusinessConfigSchema=v.pipe(v.array(FieldSchema,`Expected an array of configuration fields`),v.minLength(1,`At least one configuration parameter is required`)),SchemaBusinessConfig=v.object({schema:v.optional(SchemaBusinessConfigSchema,[])}),NUMERIC_IDENTIFIER=`(0|[1-9]\\d*)`,SEMVER_REGEX=RegExp(`^${NUMERIC_IDENTIFIER}\\.${NUMERIC_IDENTIFIER}\\.${NUMERIC_IDENTIFIER}$`);function nonEmptyString(fieldName){return v.pipe(v.string(`Expected a string for the ${fieldName}`),v.nonEmpty(`The ${fieldName} must not be empty`))}const MetadataSchema=v.object({id:v.pipe(nonEmptyString(`application id`),v.regex(/^[a-zA-Z0-9-]+$/,`The application id must contain only alphanumeric characters and dashes`)),displayName:v.pipe(nonEmptyString(`application display name`),v.maxLength(50,`The application display name must not be longer than 50 characters`)),description:v.pipe(nonEmptyString(`metadata description`),v.maxLength(255,`The metadata description must not be longer than 255 characters`)),version:v.pipe(nonEmptyString(`version`),v.regex(SEMVER_REGEX,`The version must follow semantic versioning (semver) format`))}),CommerceAppConfigSchemas={metadata:MetadataSchema,businessConfig:SchemaBusinessConfig,"businessConfig.schema":SchemaBusinessConfigSchema},CommerceAppConfigSchema=v.object({metadata:MetadataSchema,businessConfig:v.optional(SchemaBusinessConfig)}),commerceAppConfigDomainsSchema=v.picklist(Object.keys(CommerceAppConfigSchemas));function validateCommerceAppConfig(config){let validatedConfig=v.safeParse(CommerceAppConfigSchema,config);if(!validatedConfig.success)throw new CommerceSdkValidationError(`Invalid commerce app config`,{issues:validatedConfig.issues});return validatedConfig.output}function validateCommerceAppConfigDomain(config,domain){let domainSchema=v.safeParse(commerceAppConfigDomainsSchema,domain);if(!domainSchema.success)throw new CommerceSdkValidationError(`Invalid commerce app config domain`,{issues:domainSchema.issues});let domainConfigSchema=CommerceAppConfigSchemas[domain],validatedConfig=v.safeParse(domainConfigSchema,config);if(!validatedConfig.success)throw new CommerceSdkValidationError(`Invalid commerce app config: ${domain}`,{issues:validatedConfig.issues});return validatedConfig.output}const jiti=createJiti(import.meta.url),configPaths=Object.freeze([`app.commerce.config.js`,`app.commerce.config.ts`,`app.commerce.config.cjs`,`app.commerce.config.mjs`,`app.commerce.config.mts`,`app.commerce.config.cts`]);async function resolveCommerceAppConfig(cwd=process.cwd()){let packageJsonPath=await findNearestPackageJson(cwd);if(!packageJsonPath)return null;let rootDirectory=dirname(packageJsonPath);for(let configPath of configPaths){let configFilePath=await findUp(configPath,{cwd,stopAt:rootDirectory});if(configFilePath)return configFilePath}return null}async function readCommerceAppConfig(cwd=process.cwd()){let configFilePath=await resolveCommerceAppConfig(cwd);if(!configFilePath)throw Error(`Could not find a commerce app config file in the current working directory or its parents.`);let config=null;try{config=await jiti.import(configFilePath)}catch(error){let message=stringifyError(error);throw Error(`Failed to read commerce app config file at ${configFilePath}: ${message}`,{cause:error})}if(!(config&&`default`in config)||config.default===void 0||config.default===null||typeof config.default==`object`&&Object.keys(config.default).length===0)throw Error("Commerce app config file does not export a default export. Make sure you use `export default` or `module.exports = { /* your config */ }`");return config.default}async function parseCommerceAppConfig(cwd=process.cwd()){return validateCommerceAppConfig(await readCommerceAppConfig(cwd))}async function readBundledCommerceAppConfig(){try{let fileContents=await readFile(`app-management/app.commerce.manifest.json`,`utf-8`);return validateCommerceAppConfig(JSON.parse(fileContents))}catch(error){let message=stringifyError(error);throw Error(`Failed to read bundled commerce app config file: ${message}`,{cause:error})}}export{validateCommerceAppConfig as a,getExecCommand as c,resolveCommerceAppConfig as i,makeOutputDirFor as l,readBundledCommerceAppConfig as n,validateCommerceAppConfigDomain as o,readCommerceAppConfig as r,detectPackageManager as s,parseCommerceAppConfig as t,stringifyError as u};
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@adobe/aio-commerce-lib-app",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"author": "Adobe Inc.",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"private": false,
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20 <=24"
|
|
9
|
+
},
|
|
10
|
+
"license": "Apache-2.0",
|
|
11
|
+
"description": "App configuration management library for Adobe Commerce applications",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/adobe/aio-commerce-sdk/issues"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/adobe/aio-commerce-sdk.git",
|
|
18
|
+
"directory": "packages/aio-commerce-lib-app"
|
|
19
|
+
},
|
|
20
|
+
"bin": {
|
|
21
|
+
"@adobe/aio-commerce-lib-app": "./dist/es/commands/index.mjs"
|
|
22
|
+
},
|
|
23
|
+
"exports": {
|
|
24
|
+
"./config": {
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./dist/es/config/index.d.mts",
|
|
27
|
+
"default": "./dist/es/config/index.mjs"
|
|
28
|
+
},
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./dist/cjs/config/index.d.cts",
|
|
31
|
+
"default": "./dist/cjs/config/index.cjs"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"./package.json": "./package.json"
|
|
35
|
+
},
|
|
36
|
+
"imports": {
|
|
37
|
+
"#*": "./source/*.ts",
|
|
38
|
+
"#test/*": "./test/*.ts"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"package.json",
|
|
43
|
+
"CHANGELOG.md",
|
|
44
|
+
"README.md"
|
|
45
|
+
],
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@adobe/aio-commerce-lib-core": "^0.5.1",
|
|
48
|
+
"consola": "^3.4.2",
|
|
49
|
+
"jiti": "^2.6.1",
|
|
50
|
+
"valibot": "^1.1.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@aio-commerce-sdk/config-tsdown": "1.0.0",
|
|
54
|
+
"@aio-commerce-sdk/config-typedoc": "1.0.0",
|
|
55
|
+
"@aio-commerce-sdk/config-typescript": "1.0.0",
|
|
56
|
+
"@aio-commerce-sdk/scripting-utils": "0.1.1",
|
|
57
|
+
"@aio-commerce-sdk/config-vitest": "1.0.0"
|
|
58
|
+
},
|
|
59
|
+
"sideEffects": false,
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "tsdown",
|
|
62
|
+
"publint": "publint",
|
|
63
|
+
"docs": "typedoc && prettier --write '**/*.md'",
|
|
64
|
+
"assist": "biome check --formatter-enabled=false --linter-enabled=false --assist-enabled=true --no-errors-on-unmatched",
|
|
65
|
+
"assist:apply": "biome check --write --formatter-enabled=false --linter-enabled=false --assist-enabled=true --no-errors-on-unmatched",
|
|
66
|
+
"check:ci": "biome ci --formatter-enabled=true --linter-enabled=true --assist-enabled=true --no-errors-on-unmatched",
|
|
67
|
+
"format": "biome format --write --no-errors-on-unmatched",
|
|
68
|
+
"format:markdown": "prettier --no-error-on-unmatched-pattern --write '**/*.md' \"!**/{CODE_OF_CONDUCT.md,COPYRIGHT,LICENSE,SECURITY.md,CONTRIBUTING.md}\"",
|
|
69
|
+
"format:check": "biome format --no-errors-on-unmatched",
|
|
70
|
+
"lint": "biome lint --no-errors-on-unmatched",
|
|
71
|
+
"lint:fix": "biome lint --write --no-errors-on-unmatched",
|
|
72
|
+
"typecheck": "tsc --noEmit && echo '✅ No type errors found.'",
|
|
73
|
+
"test": "vitest run --coverage",
|
|
74
|
+
"test:watch": "vitest --coverage",
|
|
75
|
+
"test:ui": "vitest --ui --coverage"
|
|
76
|
+
}
|
|
77
|
+
}
|