BREAKING CHANGE(acme): Replace external acme-client with a built-in RFC8555-compliant ACME implementation and update public APIs accordingly

This commit is contained in:
2026-02-15 20:20:46 +00:00
parent 3fa34fa373
commit cf4b758800
31 changed files with 4717 additions and 3530 deletions

View File

@@ -1,4 +1,4 @@
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import { SmartAcme, certmanagers } from '../ts/index.js';
import { Http01MemoryHandler } from '../ts/handlers/Http01MemoryHandler.js';
@@ -9,23 +9,25 @@ tap.test('HTTP-01 only configuration should work for regular domains', async ()
// Stub the domain support check to always return true for testing
memHandler.checkWetherDomainIsSupported = async () => true;
const certManager = new certmanagers.MemoryCertManager();
const smartAcmeInstance = new SmartAcme({
accountEmail: 'test@example.com',
certManager: new certmanagers.MemoryCertManager(),
certManager,
environment: 'integration',
retryOptions: {},
challengeHandlers: [memHandler],
challengePriority: ['http-01'],
});
// Stub the start method to avoid actual ACME connections
smartAcmeInstance.start = async () => {
smartAcmeInstance.certmanager = certManager;
smartAcmeInstance.certmatcher = {
getCertificateDomainNameByDomainName: (domain: string) => domain.replace('*.', '')
} as any;
smartAcmeInstance.interestMap = {
checkInterest: async () => false,
addInterest: async () => ({ interestFullfilled: new Promise(() => {}) } as any)
addInterest: async () => ({ interestFullfilled: new Promise(() => {}), fullfillInterest: () => {}, destroy: () => {} } as any)
} as any;
await smartAcmeInstance.certmanager.init();
};
@@ -65,23 +67,25 @@ tap.test('should only include wildcard when explicitly requested with DNS-01', a
checkWetherDomainIsSupported: async () => true,
};
const certManager2 = new certmanagers.MemoryCertManager();
const smartAcmeInstance = new SmartAcme({
accountEmail: 'test@example.com',
certManager: new certmanagers.MemoryCertManager(),
certManager: certManager2,
environment: 'integration',
retryOptions: {},
challengeHandlers: [dnsHandler],
challengePriority: ['dns-01'],
});
// Stub the start method to avoid actual ACME connections
smartAcmeInstance.start = async () => {
smartAcmeInstance.certmanager = certManager2;
smartAcmeInstance.certmatcher = {
getCertificateDomainNameByDomainName: (domain: string) => domain.replace('*.', '')
} as any;
smartAcmeInstance.interestMap = {
checkInterest: async () => false,
addInterest: async () => ({ interestFullfilled: new Promise(() => {}) } as any)
addInterest: async () => ({ interestFullfilled: new Promise(() => {}), fullfillInterest: () => {}, destroy: () => {} } as any)
} as any;
await smartAcmeInstance.certmanager.init();
};
@@ -116,23 +120,25 @@ tap.test('should skip wildcard if requested but no DNS-01 handler available', as
const httpHandler = new Http01MemoryHandler();
httpHandler.checkWetherDomainIsSupported = async () => true;
const certManager3 = new certmanagers.MemoryCertManager();
const smartAcmeInstance = new SmartAcme({
accountEmail: 'test@example.com',
certManager: new certmanagers.MemoryCertManager(),
certManager: certManager3,
environment: 'integration',
retryOptions: {},
challengeHandlers: [httpHandler],
challengePriority: ['http-01'],
});
// Stub the start method to avoid actual ACME connections
smartAcmeInstance.start = async () => {
smartAcmeInstance.certmanager = certManager3;
smartAcmeInstance.certmatcher = {
getCertificateDomainNameByDomainName: (domain: string) => domain.replace('*.', '')
} as any;
smartAcmeInstance.interestMap = {
checkInterest: async () => false,
addInterest: async () => ({ interestFullfilled: new Promise(() => {}) } as any)
addInterest: async () => ({ interestFullfilled: new Promise(() => {}), fullfillInterest: () => {}, destroy: () => {} } as any)
} as any;
await smartAcmeInstance.certmanager.init();
};