@cedarjs/cli-helpers 8.0.0-canary.3315 → 8.0.0-canary.3317
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/auth/authTasks.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ListrRenderer, ListrTask, ListrTaskWrapper } from 'listr2';
|
|
2
|
+
import type { ExistingFiles } from '../lib/index.js';
|
|
2
3
|
export declare const getWebAppPath: () => string;
|
|
3
4
|
export declare const addApiConfig: ({ replaceExistingImport, authDecoderImport, }: {
|
|
4
5
|
replaceExistingImport: boolean;
|
|
@@ -32,6 +33,14 @@ export declare const addConfigToRoutes: () => {
|
|
|
32
33
|
* @returns Listr task
|
|
33
34
|
*/
|
|
34
35
|
export declare const generateAuthApiFiles: <Renderer extends typeof ListrRenderer>(basedir: string, webAuthn: boolean, oauth?: boolean) => ListrTask<AuthGeneratorCtx, Renderer>;
|
|
36
|
+
/**
|
|
37
|
+
* Exported for testing
|
|
38
|
+
*
|
|
39
|
+
* @returns `true` if writing `filesRecord` with the given `existingFiles`
|
|
40
|
+
* strategy writes `api/src/lib/auth.{ts,js}`, which is where the auth
|
|
41
|
+
* provider's `requireAuth` function lives
|
|
42
|
+
*/
|
|
43
|
+
export declare function writesApiAuthLib(filesRecord: Record<string, string>, existingFiles: ExistingFiles): boolean;
|
|
35
44
|
export declare const addAuthConfigToGqlApi: <Renderer extends typeof ListrRenderer, FallbackRenderer extends typeof ListrRenderer>(authDecoderImport?: string) => {
|
|
36
45
|
title: string;
|
|
37
46
|
task: (ctx: AuthGeneratorCtx, _task: ListrTaskWrapper<AuthGeneratorCtx, Renderer, FallbackRenderer>) => void;
|
|
@@ -41,9 +50,36 @@ export interface AuthGeneratorCtx {
|
|
|
41
50
|
setupMode: AuthSetupMode;
|
|
42
51
|
provider: string;
|
|
43
52
|
force: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Set by `generateAuthApiFiles`. `true` when setup writes the auth
|
|
55
|
+
* provider's `api/src/lib/auth.{ts,js}` file, replacing any existing
|
|
56
|
+
* `requireAuth` implementation
|
|
57
|
+
*/
|
|
58
|
+
apiAuthLibWritten?: boolean;
|
|
44
59
|
}
|
|
45
60
|
export declare const setAuthSetupMode: <Renderer extends typeof ListrRenderer, FallbackRenderer extends typeof ListrRenderer>(force: boolean) => {
|
|
46
61
|
title: string;
|
|
47
62
|
task: (ctx: AuthGeneratorCtx, task: ListrTaskWrapper<AuthGeneratorCtx, Renderer, FallbackRenderer>) => Promise<void>;
|
|
48
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Exported for testing
|
|
66
|
+
*
|
|
67
|
+
* @param content - The contents of requireAuth.test.{ts,js}
|
|
68
|
+
* @returns The content with the stub test case replaced, or `undefined` if
|
|
69
|
+
* the unmodified stub test case isn't part of the content
|
|
70
|
+
*/
|
|
71
|
+
export declare const replaceStubRequireAuthTestCase: (content: string) => string | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* New Cedar apps ship with a test for the `requireAuth` directive that
|
|
74
|
+
* asserts the behavior of the stub `requireAuth` function. Setting up auth
|
|
75
|
+
* replaces that stub, so this task replaces the stub test case with test
|
|
76
|
+
* cases matching the real implementation. The test is only updated when
|
|
77
|
+
* setup writes `api/src/lib/auth.{ts,js}` (for example, not when the user
|
|
78
|
+
* declines overwriting existing files). Test files that don't contain the
|
|
79
|
+
* unmodified stub test case are left as they are.
|
|
80
|
+
*/
|
|
81
|
+
export declare const updateRequireAuthTest: <Renderer extends typeof ListrRenderer, FallbackRenderer extends typeof ListrRenderer>() => {
|
|
82
|
+
title: string;
|
|
83
|
+
task: (ctx: AuthGeneratorCtx, task: ListrTaskWrapper<AuthGeneratorCtx, Renderer, FallbackRenderer>) => void;
|
|
84
|
+
};
|
|
49
85
|
//# sourceMappingURL=authTasks.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authTasks.d.ts","sourceRoot":"","sources":["../../src/auth/authTasks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"authTasks.d.ts","sourceRoot":"","sources":["../../src/auth/authTasks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAKxE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAsBpD,eAAO,MAAM,aAAa,cAA2B,CAAA;AAwDrD,eAAO,MAAM,YAAY,GAAI,+CAG1B;IACD,qBAAqB,EAAE,OAAO,CAAA;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B,SAgDA,CAAA;AAmCD,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,YAE9C,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,WA6CjD,CAAA;AAuED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,SAAS,OAAO,aAAa,OAClC,SAAS,CAAC,gBAAgB,EAAE,QAAQ,CA8CxC,CAAA;AAED,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,EAAE,UAAU,OAAO;;gBAgC1C,gBAAgB;CA0CrC,CAAA;AAED,eAAO,MAAM,iBAAiB;;;CAmB7B,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,SAAS,OAAO,aAAa,EACxE,SAAS,MAAM,EACf,UAAU,OAAO,EACjB,eAAa,KACZ,SAAS,CAAC,gBAAgB,EAAE,QAAQ,CAkDtC,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,aAAa,EAAE,aAAa,WAW7B;AASD,eAAO,MAAM,qBAAqB,GAChC,QAAQ,SAAS,OAAO,aAAa,EACrC,gBAAgB,SAAS,OAAO,aAAa,EAE7C,oBAAoB,MAAM;;gBAInB,gBAAgB,SACd,gBAAgB,CAAC,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,CAAC;CAcvE,CAAA;AAEF,MAAM,MAAM,aAAa,GACrB,OAAO,GACP,SAAS,GACT,SAAS,GACT,SAAS,CAAA;AAEb,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,aAAa,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;IACd;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,SAAS,OAAO,aAAa,EACrC,gBAAgB,SAAS,OAAO,aAAa,EAE7C,OAAO,OAAO;;gBAKL,gBAAgB,QACf,gBAAgB,CAAC,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,CAAC;CA2CzE,CAAA;AAmCD;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,GAAI,SAAS,MAAM,uBAW7D,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,GAChC,QAAQ,SAAS,OAAO,aAAa,EACrC,gBAAgB,SAAS,OAAO,aAAa;;gBAItC,gBAAgB,QACf,gBAAgB,CAAC,gBAAgB,EAAE,QAAQ,EAAE,gBAAgB,CAAC;CAmCtE,CAAA"}
|
package/dist/auth/authTasks.js
CHANGED
|
@@ -294,12 +294,21 @@ const generateAuthApiFiles = (basedir, webAuthn, oauth = false) => {
|
|
|
294
294
|
filesRecord = uniqueFilesRecord;
|
|
295
295
|
existingFiles = "FAIL";
|
|
296
296
|
}
|
|
297
|
+
ctx.apiAuthLibWritten = writesApiAuthLib(filesRecord, existingFiles);
|
|
297
298
|
return writeFilesTask(filesRecord, {
|
|
298
299
|
existingFiles
|
|
299
300
|
});
|
|
300
301
|
}
|
|
301
302
|
};
|
|
302
303
|
};
|
|
304
|
+
function writesApiAuthLib(filesRecord, existingFiles) {
|
|
305
|
+
const authLibPaths = ["ts", "js"].map(
|
|
306
|
+
(ext) => path.join(getPaths().api.src, "lib", `auth.${ext}`)
|
|
307
|
+
);
|
|
308
|
+
return Object.keys(filesRecord).some(
|
|
309
|
+
(filePath) => authLibPaths.includes(filePath) && (existingFiles === "OVERWRITE" || !fs.existsSync(filePath))
|
|
310
|
+
);
|
|
311
|
+
}
|
|
303
312
|
function findExistingFiles(filesMap) {
|
|
304
313
|
return Object.keys(filesMap).filter((filePath) => fs.existsSync(filePath)).map((filePath) => filePath.replace(getPaths().base, ""));
|
|
305
314
|
}
|
|
@@ -338,6 +347,65 @@ const setAuthSetupMode = (force) => {
|
|
|
338
347
|
}
|
|
339
348
|
};
|
|
340
349
|
};
|
|
350
|
+
const STUB_REQUIRE_AUTH_TEST_CASE = ` it('requireAuth has stub implementation. Should not throw when current user', () => {
|
|
351
|
+
// If you want to set values in context, pass it through e.g.
|
|
352
|
+
// mockRedwoodDirective(requireAuth, { context: { currentUser: { id: 1, name: 'Lebron McGretzky' } }})
|
|
353
|
+
const mockExecution = mockRedwoodDirective(requireAuth, { context: {} })
|
|
354
|
+
|
|
355
|
+
expect(mockExecution).not.toThrowError()
|
|
356
|
+
})`;
|
|
357
|
+
const REQUIRE_AUTH_TEST_CASES = ` it('throws when there is no current user', () => {
|
|
358
|
+
const mockExecution = mockRedwoodDirective(requireAuth, { context: {} })
|
|
359
|
+
|
|
360
|
+
expect(mockExecution).toThrowError("You don't have permission to do that.")
|
|
361
|
+
})
|
|
362
|
+
|
|
363
|
+
it('does not throw when there is a current user', () => {
|
|
364
|
+
// The mocked user should have the same shape as what getCurrentUser()
|
|
365
|
+
// in api/src/lib/auth returns
|
|
366
|
+
const mockExecution = mockRedwoodDirective(requireAuth, {
|
|
367
|
+
context: { currentUser: { id: 1 } },
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
expect(mockExecution).not.toThrowError()
|
|
371
|
+
})`;
|
|
372
|
+
const replaceStubRequireAuthTestCase = (content) => {
|
|
373
|
+
const eol = content.includes("\r\n") ? "\r\n" : "\n";
|
|
374
|
+
const normalizedContent = content.replaceAll("\r\n", "\n");
|
|
375
|
+
if (!normalizedContent.includes(STUB_REQUIRE_AUTH_TEST_CASE)) {
|
|
376
|
+
return void 0;
|
|
377
|
+
}
|
|
378
|
+
return normalizedContent.replace(STUB_REQUIRE_AUTH_TEST_CASE, REQUIRE_AUTH_TEST_CASES).replaceAll("\n", eol);
|
|
379
|
+
};
|
|
380
|
+
const updateRequireAuthTest = () => ({
|
|
381
|
+
title: "Updating requireAuth directive test...",
|
|
382
|
+
task: (ctx, task) => {
|
|
383
|
+
if (!ctx.apiAuthLibWritten) {
|
|
384
|
+
task.skip(
|
|
385
|
+
"Keeping the requireAuth directive test as is, because the existing requireAuth implementation is kept"
|
|
386
|
+
);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const testFilePath = ["ts", "js"].map(
|
|
390
|
+
(ext) => path.join(
|
|
391
|
+
getPaths().api.directives,
|
|
392
|
+
"requireAuth",
|
|
393
|
+
`requireAuth.test.${ext}`
|
|
394
|
+
)
|
|
395
|
+
).find((filePath) => fs.existsSync(filePath));
|
|
396
|
+
if (!testFilePath) {
|
|
397
|
+
task.skip("No requireAuth directive test found");
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
const content = fs.readFileSync(testFilePath, "utf-8");
|
|
401
|
+
const newContent = replaceStubRequireAuthTestCase(content);
|
|
402
|
+
if (newContent === void 0) {
|
|
403
|
+
task.skip("Keeping the customized requireAuth directive test as is");
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
fs.writeFileSync(testFilePath, newContent);
|
|
407
|
+
}
|
|
408
|
+
});
|
|
341
409
|
export {
|
|
342
410
|
addApiConfig,
|
|
343
411
|
addAuthConfigToGqlApi,
|
|
@@ -348,5 +416,8 @@ export {
|
|
|
348
416
|
getWebAppPath,
|
|
349
417
|
hasAuthProvider,
|
|
350
418
|
removeAuthProvider,
|
|
351
|
-
|
|
419
|
+
replaceStubRequireAuthTestCase,
|
|
420
|
+
setAuthSetupMode,
|
|
421
|
+
updateRequireAuthTest,
|
|
422
|
+
writesApiAuthLib
|
|
352
423
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupHelpers.d.ts","sourceRoot":"","sources":["../../src/auth/setupHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAGvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAWjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"setupHelpers.d.ts","sourceRoot":"","sources":["../../src/auth/setupHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAGvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAWjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAWtD,YAAY,EAAE,gBAAgB,EAAE,CAAA;AAEhC,eAAO,MAAM,mBAAmB,GAAI,OAAO,IAAI;;;;EAoB9C,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,UAAU,CAAC,EAAE,CAAC,SAAS,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC,EAAE,CAAA;IACxD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;IAChB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AASD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAU,4HAYvC,eAAe,kBAkFjB,CAAA"}
|
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
addConfigToWebApp,
|
|
14
14
|
setAuthSetupMode,
|
|
15
15
|
createWebAuth,
|
|
16
|
-
generateAuthApiFiles
|
|
16
|
+
generateAuthApiFiles,
|
|
17
|
+
updateRequireAuthTest
|
|
17
18
|
} from "./authTasks.js";
|
|
18
19
|
const standardAuthBuilder = (yargs) => {
|
|
19
20
|
return yargs.option("force", {
|
|
@@ -53,6 +54,7 @@ const standardAuthHandler = async ({
|
|
|
53
54
|
[
|
|
54
55
|
setAuthSetupMode(forceArg),
|
|
55
56
|
generateAuthApiFiles(basedir, webAuthn, oauth),
|
|
57
|
+
updateRequireAuthTest(),
|
|
56
58
|
addConfigToWebApp(),
|
|
57
59
|
createWebAuth(basedir, webAuthn),
|
|
58
60
|
addConfigToRoutes(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/cli-helpers",
|
|
3
|
-
"version": "8.0.0-canary.
|
|
3
|
+
"version": "8.0.0-canary.3317",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
"test:watch": "vitest watch"
|
|
126
126
|
},
|
|
127
127
|
"dependencies": {
|
|
128
|
-
"@cedarjs/project-config": "8.0.0-canary.
|
|
129
|
-
"@cedarjs/telemetry": "8.0.0-canary.
|
|
128
|
+
"@cedarjs/project-config": "8.0.0-canary.3317",
|
|
129
|
+
"@cedarjs/telemetry": "8.0.0-canary.3317",
|
|
130
130
|
"@listr2/prompt-adapter-enquirer": "4.3.2",
|
|
131
131
|
"@opentelemetry/api": "1.9.1",
|
|
132
132
|
"ansis": "4.4.0",
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"yargs-parser": "21.1.1"
|
|
147
147
|
},
|
|
148
148
|
"devDependencies": {
|
|
149
|
-
"@cedarjs/framework-tools": "8.0.0-canary.
|
|
149
|
+
"@cedarjs/framework-tools": "8.0.0-canary.3317",
|
|
150
150
|
"@types/dotenv-defaults": "^5.0.0",
|
|
151
151
|
"@types/lodash": "4.17.25",
|
|
152
152
|
"@types/pascalcase": "1.0.3",
|